docs: решено оставить очередь своей таблицей коллекцией PocketBase
- заведены записка разведки job-queue-choice и ADR: готовые библиотеки River и goqite отвергнуты, захват сворачивается в один запрос с RETURNING - в architecture.md уточнён принцип «очередь таблицей» и закрыт открытый вопрос «Очередь», кроме холостого опроса - задача pocketbase-storage забрала очередь себе: границы, счётчик попыток, состояние «мертва» и оракулы
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Записи, метаданные и файлы лежат порознь, и владелец не видит их ничем, кроме консоли на сервере: панель PocketBase покажет и то и другое, только если они переедут к ней.
|
||||
- **Зачем:** Записи, метаданные и файлы лежат порознь, и владелец не видит их ничем, кроме консоли на сервере: панель PocketBase покажет их, только если они переедут к ней. Заодно переписывается захват задачи: сегодня это два запроса без транзакции, а падающая всегда задача падает вечно.
|
||||
|
||||
PocketBase встраивается библиотекой в тот же бинарник и приносит хранилище,
|
||||
учётные записи и панель администратора разом. Конвейер и оба входа работают
|
||||
@@ -20,12 +20,22 @@ PocketBase встраивается библиотекой в тот же бин
|
||||
Данные не переносим — база заводится с чистого листа, и это решение принято
|
||||
сознательно.
|
||||
|
||||
**Очередь переписывается тем же заходом.** Разведка `job-queue-choice` 2026-08-11
|
||||
[отвергла готовые библиотеки](../../docs/adr/ADR-2026-08-11-queue-as-pocketbase-collection.md):
|
||||
очередь остаётся своей таблицей, но становится коллекцией PocketBase. Захват
|
||||
сворачивается в один запрос с `RETURNING`, число попыток ложится колонкой,
|
||||
нарастающая пауза выражается существующим `delay_time`, а исчерпавшая попытки
|
||||
задача переходит в состояние «мертва» вместо `is_error = 1`. Сравнение
|
||||
кандидатов — [docs/research/job-queue.md](../../docs/research/job-queue.md).
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- таблицы `files` и `transcribe_jobs`, каталог `migrations/` и весь механизм
|
||||
goose;
|
||||
- `internal/adapter/repo/sqlite` целиком, включая захват задачи через
|
||||
`FindAndAcquire`;
|
||||
- состав колонок очереди: прибавляется число попыток, а `is_error` уступает
|
||||
место состоянию «мертва» в перечне состояний задачи;
|
||||
- `internal/contract`, интерфейсы `FileRepository` и `TranscriptJobRepository`;
|
||||
- ключ конфигурации `[database] path`, ключ `[storage] path` и раскладка
|
||||
каталога `data/`;
|
||||
@@ -47,14 +57,19 @@ PocketBase встраивается библиотекой в тот же бин
|
||||
- Сервис поднимается на чистом каталоге данных, накатывает свою схему сам и
|
||||
принимает запись обоими входами. Оракул — запуск на пустом `data/` и прогон
|
||||
записи из Telegram и через `POST /api/audio` до состояния `done`.
|
||||
- Захват задачи воркером не выдаёт одну запись двум вызывающим. Оракул — тест
|
||||
на трёх параллельных вызовах захвата по одному состоянию: ровно один
|
||||
получает запись.
|
||||
- Задача, брошенная на середине, достаётся снова по истечении срока захвата.
|
||||
Оракул — тест с проставленным задним числом `acquire_time`.
|
||||
- Принятая запись видна в панели строкой и скачивается из неё файлом. Оракул —
|
||||
прогон записи через `POST /api/audio` на пустом каталоге, затем запрос
|
||||
`/api/files/...` за тем же файлом: длина совпадает с загруженной.
|
||||
- Захват задачи воркером идёт одним запросом и не выдаёт одну запись двум
|
||||
вызывающим. Оракул — тест на трёх параллельных вызовах захвата по одному
|
||||
состоянию: ровно один получает запись.
|
||||
- Задача, брошенная на середине, достаётся снова по истечении срока захвата, а
|
||||
падающая всегда — уходит в «мертва» и из выборки исчезает. Оракулы — тест с
|
||||
проставленным задним числом `acquire_time` и тест с шагом, падающим на каждой
|
||||
попытке: после заданного их числа задача не выдаётся, а её состояние видно
|
||||
отбором.
|
||||
- Принятая запись видна в панели строкой и скачивается по ссылке
|
||||
`/api/files/...` тем же файлом. Оракулы — прогон записи через
|
||||
`POST /api/audio` на пустом каталоге, затем поиск её строки в коллекции задач
|
||||
на `/_/` по идентификатору и запрос `/api/files/...` за тем же файлом: длина
|
||||
совпадает с загруженной.
|
||||
- `docs/database.md` описывает новую схему, а старые упоминания goose и goqu из
|
||||
документов канона убраны. Оракул — `task gate`, шаг `docs.py check`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user