diff --git a/docs/adr/0009-world-control.md b/docs/adr/0009-world-control.md index 50bd601..9326749 100644 --- a/docs/adr/0009-world-control.md +++ b/docs/adr/0009-world-control.md @@ -17,7 +17,7 @@ через `TriggerDagRunOperator`, дожидаясь его завершения. Снят с паузы — стенд живёт день за днём; поставлен на паузу — мир встал на границе модельных суток. -Генератор задача зовёт `DockerOperator`: поднимает образ +Генератор задача зовёт через `DockerOperator`: тот поднимает образ `clickstream-generator:local` — тот самый канонический контейнер, внутри которого [спека генератора](../specs/2026-08-01-generator.md) обещает побайтовую воспроизводимость, — в сети стенда, командой `batch` или `live`. @@ -75,12 +75,18 @@ и выключатель. Это [ADR 0003](0003-dag-run-state.md) в действии: зелёный конец графа не должен переживать отказ выше. -**Позиция ставится, а не увеличивается.** Правило дешевле сторожа. Если -автоматика прилетит поверх ручного прогона, худшее — день сыгран дважды: номера -событий детерминированы, повтор схлопнет `ReplacingMergeTree`, а позиция -останется верной. Увеличение на единицу в том же случае молча проглотило бы -день, и мир получил бы дыру, которую никто не заметит. Ни пул как мьютекс, ни -проверка «а не идёт ли другой прогон» после этого не нужны. +**Позиция ставится, а не увеличивается.** Правило дешевле сторожа. Если прогон +выключателя наложится на ручной, худшее — день сыгран дважды: номера событий +детерминированы, повтор схлопнет `ReplacingMergeTree`, а позиция останется +верной. Увеличение на единицу в том же случае молча проглотило бы день, и мир +получил бы дыру, которую никто не заметит. Ни пул как мьютекс, ни проверка «а не +идёт ли другой прогон» после этого не нужны. + +Худший исход у правила всё-таки есть, и он мягкий: работник, кончивший позже, +ставит позицию по своему последнему дню и может отодвинуть её назад — так +бывает, если долгий живой день закончится после разгона на три дня вперёд. +Тогда часть дней переигрывается. Это дешевле дыры: переигранный день склеится, +пропущенный не найдётся никогда. **Плата — сокет докера внутри Airflow.** Доступ к нему равен праву root на машине, и пользователю `airflow` он открывается через GID группы `docker`,