8.4 Цепочки
Цепочка связывает асинхронные шаги так, что выполняется либо вся цепочка, либо возвращается первая необработанная ошибка.
let page = Users.get(id)
-> (Orders.recent(it.id), Recs.for(it.id))
-> (orders, recs) => Page{ orders, recs }
~> Audit.log("page", id)
!> Timeout => Page.empty()
within PAGE_DEADLINE
retry 2
let html = await pageСинтаксис: голова ( звено )* ( суффикс )*, где звено — -> шаг, ?-> шаг, ~> шаг, !> образец => обработчик; суффикс — within e, retry e (on Типы)? (backoff e)?.
Голова — выражение типа Task<T, E>, вызов приостанавливаемой функции (поднимается в Task по §6.3) или любое другое выражение (готовое значение).
Шаг — одно из:
- выражение, использующее
it— значение предыдущего шага; - лямбда
x => eили с деструктуризацией(a, b) => e; - кортеж
(e1, …, en)— fan-out: каждыйeiвычисляется как отдельная задача параллельно (внутриeiдоступенit); результат — кортеж значений; первая ошибка отменяет остальные.
Результат шага, являющийся вызовом приостанавливаемой функции или Task, ожидается. Если тип результата содержит ошибки и шаг вернул ошибку, оставшиеся звенья справа пропускаются до ближайшего подходящего !>.
| Звено | Семантика |
|---|---|
-> шаг | выполнить шаг над значением слева |
?-> шаг | если значение слева none, результат цепочки — none (к типу добавляется none), иначе выполнить шаг |
~> шаг | запустить шаг в фоне; значение цепочки остаётся прежним; ошибки шага пишутся в лог и не пробрасываются; фоновая задача живёт в фоновом scope узла (§8.5) |
!> P => h | ловит ошибку, соответствующую образцу P, из всей части цепочки левее; значение h заменяет значение левой части, и выполнение продолжается со звеньев правее; h может сделать fail |
within d | дедлайн на всю часть левее; превышение — ошибка Timeout (её может поймать !> правее) |
retry n | повторить всю часть левее до n раз при ошибках Timeout | Unavailable (или указанных в on); backoff по умолчанию exp(100ms, 10s) с джиттером |
Тип цепочки — Task<T, E>, где T — тип последнего значения (с none, если есть ?->), E — объединение ошибок всех шагов минус пойманные !> плюс ошибки обработчиков, плюс Timeout при within.
Запуск: цепочка ленива. Её запускает await, spawn, передача в lazy-параметр или использование в позиции инструкции (тогда она ожидается неявно, как вызов приостанавливаемой функции).
it относится к ближайшей объемлющей цепочке; во вложенной цепочке внешнее значение нужно назвать лямбдой.
Связанные диагностики
См. также
Исходник: docs/spec/oxl-standard.md