- порядок беклога и роадмапа назначен слоями: проверки, которым можно верить → долги входа → владелец записи и контракт API → конвейер под тестами → приложение и возможности поверх; у каждого движения записана причина; - заведены восемь задач под пункты «Завершения», которых не закрывала ни одна запись, — цель any-audio-source была без задач вовсе; - у четырёх задач сняты критерии, требовавшие того, что делает задача ниже по очереди; исправлены ссылки на несуществующий repo/sqlite и на отменённую разведку об очереди.
48 lines
3.9 KiB
Markdown
48 lines
3.9 KiB
Markdown
# 🧹 Прервать шаг конвейера отменой контекста
|
|
|
|
- **Тип:** chore
|
|
- **Категория:** Очередь — Отмена контекста трогает те же шаги, что и таймауты: одна окрестность кода, два захода дороже одного.
|
|
- **Зачем:** Воркер читает ctx только между итерациями: остановка контейнера ждёт конца шага, а на занятом писателе один запрос к хранилищу держится до 9,5 секунды при мягком таймауте в 5.
|
|
|
|
Долг назван в `docs/architecture.md` — раздел про capability `pipeline`, где
|
|
отмена контекста посреди шага перечислена среди неописанного. Ревью задачи
|
|
`pocketbase-storage` 2026-08-12 его уточнило, и уточнение меняет способ починки:
|
|
**передать `ctx` по всему коду недостаточно**. Хранилище не принимает контекста ни в
|
|
одном из методов записи — ни в сохранении записи, ни в транзакции, ни в чтении по
|
|
идентификатору; отменять там нечем без перехода части записи на сырые запросы,
|
|
у которых контекст есть.
|
|
|
|
Число снято на прогоне: под внешней эксклюзивной блокировкой файла базы захват
|
|
задачи держится 9,53 секунды (таймаут занятости хранилища — 10 секунд) и
|
|
возвращает отличимый отказ, а не «работы нет».
|
|
|
|
## Затрагивает
|
|
|
|
- цикл воркера `internal/controller/worker`;
|
|
- сигнатуры шагов конвейера в `internal/service`;
|
|
- договор ядра с хранилищем `internal/contract` и его реализация в
|
|
`internal/adapter/repo/pocketbase`;
|
|
- таймауты мягкой и жёсткой остановки — конфиг, `[server] shutdown_timeout` и
|
|
`force_shutdown_timeout`;
|
|
- спека `pipeline`: сегодня раздел `Purpose` объявляет отмену контекста
|
|
неописанной.
|
|
|
|
## Критерии приёмки
|
|
|
|
- Шаг, идущий дольше мягкого таймаута, обрывается по сигналу остановки. Оракул —
|
|
тест с шагом, спящим дольше таймаута: остановка укладывается в бюджет, а не
|
|
доживает до жёсткой.
|
|
- Оборванный шаг оставляет задачу пригодной к повтору. Оракул — тот же тест:
|
|
после остановки задача не захвачена и выдаётся следующему.
|
|
- Отмена не путается с отказом: прерванный шаг не тратит попытку и не уходит в
|
|
«мертва». Оракул — тест на трёх прерываниях подряд, счётчик попыток не растёт
|
|
до предела.
|
|
- Спека `pipeline` описывает отмену, и раздел `Purpose` её больше не числит
|
|
неописанной. Оракул — `openspec validate --strict`.
|
|
|
|
## Рамки
|
|
|
|
Таймаут занятости хранилища этой задачей не трогаем: он свойство библиотеки, а не
|
|
наше. Мягкая остановка в 5 секунд может оказаться меньше неотменяемого минимума —
|
|
тогда число меняется, и это решение человека.
|