По одной строке на каждый член Solo, контекста его задач, задач, которые он
возвращает, его очереди и его накопителей, с разделом, где о нём рассказано.
По одной строке и на каждый параметр методов, которые создают задачи. Что
solo берёт из ядра, перечислено там, где оно объяснено. Остальной ctx —
в разделе «Контекст коротко»
справочника async_job, а value, done или cancel() задачи — в разделе
«Задачи и результаты» страницы о задачах.
Solo<S> служит базовым классом контроллера. Его члены делятся на четыре
группы по тому, кто ими пользуется: весь процесс, вызывающий код, подкласс
и переопределение в подклассе.
| Член |
Что делает |
Где |
Solo.observer |
Один наблюдатель всех контроллеров процесса, который смотрит и ни за что не отвечает |
«Наблюдение за всеми контроллерами» |
Solo.unansweredHandler |
SoloUnansweredHandler, который вместо зоны принимает ошибки, за которые никто не ответил |
«Ответ за ошибку» |
Solo.debug |
Колбэк, который печатает трассу очереди, состояния и закрытия каждого контроллера, а жизнь каждой задачи печатает Job.debug |
«Логи» |
| Член |
Что делает |
Где |
currentState |
Состояние для читателя вне задачи, прочитанное без контрольной точки |
«Наблюдение за состоянием» |
addListener(listener) |
Вызывает слушателя синхронно внутри каждого изменения состояния |
«Наблюдение за состоянием» |
removeListener(listener) |
Снимает самую раннюю регистрацию, равную слушателю |
«Наблюдение за состоянием» |
isClosed |
Был ли вызван close() |
«Три способа остановиться» |
isDraining |
Проходит ли ещё очередь close() с дренажом |
«Три способа остановиться» |
isFinished |
Закончилось ли закрытие, после которого состояние больше не меняется |
«externalSetState» |
pending |
Что держит контроллер прямо сейчас, в том числе идущая задача, или null |
«Что удерживает контроллер» |
cancelAll() |
Очищает очередь и отменяет работающую задачу; контроллер остаётся открытым. С force: true убирает и задачи в очереди, созданные с cancellable: false, а reason: задаёт причину, с которой кончается каждая снятая задача |
«Три способа остановиться» |
close() |
Перестаёт принимать работу и закрывается, отменяя то, что ждёт в очереди и работает, или, с mode: SoloCloseMode.drain, сначала проходя очередь |
«Три способа остановиться» |
Из этого контроллер строит свой конструктор и свои методы, а вызывающий код
видит уже их. Все члены здесь защищённые.
| Член |
Что делает |
Где |
Solo(initialState) |
Конструктор, который подкласс вызывает как super(initialState), с первым состоянием |
«Быстрый старт» |
enqueue(body) |
Создаёт и ставит в очередь задачу, которую обычно возвращает метод контроллера |
«Создание и запуск задач» |
job(body) |
Создаёт задачу без очереди, для enqueueJob или для ctx.run ребёнком |
«Создание и запуск задач» |
enqueueJob(job) |
Ставит задачу, сделанную job, в очередь по Policy: в хвост, а с first: true в голову |
«Очередь и политики» |
collect(handler) |
Создаёт накопитель, который отдаёт одной задаче список событий её группы |
«Один запрос на строку журнала» |
accumulate(handler, merge: ...) |
Создаёт накопитель, который сливает события группы в одно значение |
«Настройки, сохраняемые на каждом щелчке» |
queue |
Задачи, которые ждут запуска, в виде SoloQueue |
«Работа с очередью напрямую» |
lastJobWhere(test) |
Последняя задача очереди, прошедшая проверку, иначе работающая, если она её проходит и не отменена, иначе null |
«Работа с очередью напрямую» |
current |
Работающая корневая задача или null, когда контроллер простаивает |
«Работа с очередью напрямую» |
hasListeners |
Есть ли хоть один слушатель |
«Наблюдение за состоянием» |
externalSetState(state) |
Отражает состояние, которое внешний источник уже изменил |
«externalSetState» |
Их вызывает движок. Хуки по умолчанию ничего не делают, кроме двух, которые
передают ошибку дальше, а publish доставляет состояние: переопределение
сначала вызывает super.publish. Все члены здесь тоже защищённые. Dart
не переносит аннотацию на переопределение: чтобы остаться защищённым,
переопределение повторяет @protected.
| Член |
Что делает |
Где |
onStart(job) |
Тело задачи вот-вот начнёт работу |
«Наблюдение за всеми контроллерами» |
onFinish(job) |
У задачи появился исход, в том числе у задачи, отброшенной до старта |
«Наблюдение за всеми контроллерами» |
onError(job, error, stackTrace, answer: ...) |
Слышит каждую ошибку, на которую наткнулась задача, и сообщает о ней, ничего не двигая |
«Отправка ошибки» |
onUnanswered(job, error, stackTrace) |
Отвечает за ошибку, которую не несёт ни один исход, и за Failed, который никто не наблюдал, по умолчанию отдавая её Solo.unansweredHandler или зоне |
«Ответ за ошибку» |
onLog(job, message) |
Задача вызвала ctx.log |
«Логи» |
onChange(transition) |
Состояние изменилось, и SoloTransition говорит, какая задача его изменила |
«Наблюдение за всеми контроллерами» |
onClose() |
Движок вот-вот закончит закрытие, и здесь освобождают то, что контроллер держит помимо задач |
«externalSetState» |
onListenerError(error, stackTrace) |
Слушатель бросил ошибку, которая по умолчанию идёт в зону |
«Наблюдение за состоянием» |
publish(previous, current) |
Вызывает слушателей и служит швом для доставки другого рода |
«Своя доставка» |
enqueue, job, collect и accumulate первым берут тело (у накопителя это
обработчик, который получает ещё и события своей группы), а за ним эти
именованные параметры. Первый аргумент типа у каждого — рабочий тип, о нём
раздел «Состояние и правила» страницы
о состоянии.
| Параметр |
У кого |
Что делает |
Где |
key |
enqueue, job, collect, accumulate |
Ключ задачи, по которому её находит Policy и под которым она без describe печатается: Job(key) |
«Создание и запуск задач» |
describe |
enqueue, job, collect, accumulate |
Подпись после ключа для логов, наблюдателей и toString(): Job(key: label) |
«Создание и запуск задач» |
policy |
enqueue, collect, accumulate |
Policy у enqueue, которая решает, что делать с задачей, чей ключ уже стоит в очереди или работает, или AccumulationPolicy у накопителя, которая решает, к какой ждущей группе присоединяется событие |
«Очередь и политики», «Выбор места присоединения событий» |
timing |
collect, accumulate |
Когда группа может стартовать, AccumulationTiming: debounce или throttle |
«Выбор момента готовности группы» |
merge |
accumulate |
Обязательная, синхронная и чистая функция, которая сливает пришедшее событие со значением группы |
«Запуск, отмена и ошибки» |
canStart |
enqueue, job, collect, accumulate |
Спрашивается один раз, перед самым стартом задачи, а false кончает её Cancelled(rules: canStart) |
«Правила» |
keepWhile |
enqueue, job, collect, accumulate |
Держит задачу, пока состояние это позволяет, а false отменяет её с Cancelled(rules: keepWhile) |
«Правила» |
cancellable |
enqueue, job, collect, accumulate |
false отклоняет ручную отмену и отмену родителя, а закрытие — когда задача уже работает: стоящую в очереди close() убирает |
«Вся задача» |
timeout |
enqueue, job, collect, accumulate |
Срок, отсчитанный от старта тела, по истечении которого задача кончается Cancelled(timeout); с cancellable: false вызов бросает ArgumentError |
«Срок задачи» |
ifFailed |
enqueue, job, collect, accumulate |
Состояние, которое записывается, когда задача упала, после того как закончились тело, его дети и очистка |
«Обработчики» |
isExpectedError |
enqueue, job, collect, accumulate |
Называет ошибки, которых задача ждёт: названную ошибку слышит onError с never, а отвечать за неё никого не просят |
«Назвать ожидаемые ошибки» |
ifCancelled |
enqueue, job, collect, accumulate |
Состояние, которое записывается, когда задачу отменили, после того как закончились тело, его дети и очистка |
«Обработчики» |
Что тело solo получает как ctx: JobContext ядра плюс состояние, суженное
до рабочего типа W задачи. join, abandonable, onDispose и остальной
ctx принадлежат ядру и описаны в разделе
«Контекст коротко» справочника
async_job. Здесь контрольные точки ядра, check() и ждущие методы,
спрашивают и правила задачи, как это делает ctx.state; спрашивает их
и ctx.each.
| Член |
Что делает |
Где |
ctx.state |
Состояние как W, прочитанное в контрольной точке, где состояние, которое правила задачи отвергают, отменяет задачу |
«Чтение и изменение состояния» |
ctx.stateAs<T>() |
Состояние, суженное дальше до T, с отменой задачи при несовпадении |
«Чтение и изменение состояния» |
ctx.emit(next) |
Единственный способ тела записать состояние, синхронный |
«Чтение и изменение состояния» |
ctx.child(body) |
Делает незапущенного ребёнка этого контроллера по правилам этой задачи, с её рабочим типом W и keepWhile, для кода, у которого есть только контекст |
«Дочерние задачи и цепочки» |
ctx.run(child) |
Запускает ребёнка, сделанного job(...) этого контроллера или ctx.child, и возвращает его значение; задачу ядра или другого контроллера отвергает с ArgumentError |
«Дочерние задачи и цепочки» |
ctx.start(child) |
Запускает такого ребёнка сразу и оставляет его исход тому, кто его держит |
«Дочерние задачи и цепочки» |
ctx.runAll(children) |
Запускает таких детей рядом и останавливает остальных, как только один из них пошёл не так |
«Дочерние задачи и цепочки» |
ctx.each(stream, onData) |
Запускает ребёнка, который отдаёт события стрима onData по одному, вместе с SoloContext ребёнка, в контрольной точке, где состояние, которое правила задачи отвергают, вместо этого отменяет задачу |
«Обработка стрима» |
Что возвращают enqueue, job, enqueueJob и add накопителя и что отдают
queue.jobs, current и lastJobWhere: Job<T> ядра плюс очередь. value,
done, outcome, cancel() и ignoreFailure() принадлежат ядру и стоят
в таблице раздела «Задачи и результаты» страницы
о задачах. Метод, который зовёт экран, объявляет Job<T>, а SoloJob<T>
только для вызывающего, который читает isQueued. Метод, который делает
ребёнка для ctx.run, объявляет SoloJob<T>: ctx.run берёт ChildJob<T>,
а им SoloJob<T> является, Job<T> — нет.
Тип queue. Удаление трогает только ждущие задачи: работающая задача очереди
не принадлежит. Задача, созданная с cancellable: false, остаётся, если вызов
не говорит force: true, а удалённая задача кончается Cancelled(manual) или
с причиной reason:, которую передал вызов.
Тип, который возвращают collect и accumulate. Держите один экземпляр в поле
late final: события объединяются только внутри одного накопителя, даже под
одним ключом.
| Член |
Что делает |
Где |
accumulator.add(event) |
Добавляет событие в ждущую группу или начинает новую и возвращает задачу группы, которую каждый вызывающий продолжает через shared() |
«Запуск, отмена и ошибки» |
| Тип |
Что это |
Где |
Policy |
Что enqueueJob и enqueue делают с задачей, чей ключ уже ждёт в очереди или работает: sequential, droppable, keepLatest или restart |
«Очередь и политики» |
SoloCloseMode |
Как останавливается close(): cancel или drain |
«Три способа остановиться» |
SoloUnansweredHandler |
Тип Solo.unansweredHandler: функция от контроллера, задачи, ошибки и её стека |
«Ответ за ошибку» |
SoloObserver |
Что принимает Solo.observer, один наблюдатель или несколько, объединённых SoloObserver.all: onStart, onFinish, onError, onLog, onChange и onClose каждого контроллера, плюс onCreate |
«Наблюдение за всеми контроллерами» |
SoloTransition |
Одно изменение состояния: состояния до и после, задача, которая его сделала, и ревизия, которая растёт на единицу с каждым изменением |
«Наблюдение за всеми контроллерами» |
SoloPending |
Что возвращает pending: SoloPendingJob со своими job и phase, SoloPendingQueue со своими jobs или SoloPendingStream |
«Что удерживает контроллер» |
SoloPhase |
Где стоит задача SoloPendingJob: body, children или cleanup |
«Что удерживает контроллер» |
SoloStream |
Миксин, который добавляет broadcast-стрим stream состояний |
«Наблюдение за состоянием» |
AccumulationPolicy |
В какую ждущую группу входит событие: join, adjacent или replace |
«Выбор места присоединения событий» |
AccumulationTiming |
Когда группа может стартовать: debounce или throttle |
«Выбор момента готовности группы» |
SoloCancelReason |
База причин, которые solo добавляет к причинам ядра: RulesCancelReason, ClosedCancelReason, DuplicateCancelReason и ReplacedCancelReason |
«Сведения об отмене» |