--- referenceVersion: 2 --- # Параллельность и ресурсы `concurrency` управляет ветками, допуском запусков и временным владением ресурсом. Параметры зависят от места применения. ## Параметры | Поле | Где и для чего | По умолчанию | | --- | --- | --- | | `limit` | Допуск запусков / веток / владельцев ресурса | 4 / 2 / 1 | | `on_busy` | Для запусков и ресурса: ожидание или иная реакция | `wait` | | `supersession_key` | Эквивалентность заменяемых запусков | Не задано | | `branches` | Именованные ветки `steps` + `outputs` | Для параллельных веток | | `on_error` | Ошибки веток: `fail` или `collect` | `fail` | | `resource` | Ключ ресурса внутри аккаунта | Для резервирования | | `lifetime` | Владение до конца участка (`step`) или запуска (`run`) | `step` | | `protected` | Защита короткой внешней записи | false | | `steps`, `outputs` | Участок под резервом и его результат | Пустые | | `when` | Условие выполнения участка/ветвления | Без условия | ## Пример ```yaml [Две независимые ветки] - id: parallel concurrency: limit: 2 on_error: collect branches: products: steps: - id: fetch block: http params: url: "{inputs.products_url}" outputs: items: "{fetch.json}" prices: steps: - id: fetch block: http params: url: "{inputs.prices_url}" outputs: items: "{fetch.json}" ``` Ветки используют разные источники. Одинаковое внутреннее имя `fetch` не смешивает результаты. ## Результат Ветки: `branches: {name: {status, output, error}}`. Резерв: `acquired`, `output`; при пропуске — `false`, `null`. Допуск запусков задаёт порядок выполнения и не создаёт результат блока. ## Поведение Ветвление дожидается всех веток; ручное ожидание не считается ошибкой. Лимиты веток и запусков действуют одновременно. Для очередей и резервов нужно постоянное хранилище; SDK без него отказывает до действий. ## Запуски workflow ```yaml [Поля верхнего уровня workflow] concurrency: limit: 1 on_busy: wait ``` `limit=1` сериализует запуски. `latest_waiting` заменяет эквивалентную ожидающую работу, `supersede` также запрашивает остановку активной; оба требуют `limit=1` и `supersession_key`. ## Резервирование ```yaml [Занять ресурс до окончания запуска] - id: claim concurrency: resource: "{inputs.resource_key}" limit: 1 lifetime: run on_busy: skip ``` При занятости: `wait` — ждать, `skip` — пропустить без действий и без заявки на ожидание, `fail` — ошибка. Пустой участок допустим только для `lifetime=run`. Резерв сохраняется через согласование и перезапуск. Повторное получение своим запуском использует тот же резерв; после завершения он освобождается. Воркеры получают ресурс согласованно; разные `limit` одного ключа отклоняются. Внутри занятого участка можно получить только пустой резерв `lifetime: run` с `on_busy: skip` или `fail`, до начала защищённой записи. Вложенное ожидание запрещено; ключ не содержит секретов. Например, временное владение изображением и постоянная отметка «уже использовано» — разные вещи: постоянная история хранится в данных приложения. ## Защита записи `protected` откладывает отмену на время короткой записи и сохранения результата. Согласование внутри участка запрещено. Если запись могла выполниться, ресурс остаётся на проверку вместо автоматического освобождения и повтора.