docs: решено оставить очередь своей таблицей коллекцией PocketBase

- заведены записка разведки job-queue-choice и ADR: готовые библиотеки River и
  goqite отвергнуты, захват сворачивается в один запрос с RETURNING
- в architecture.md уточнён принцип «очередь таблицей» и закрыт открытый вопрос
  «Очередь», кроме холостого опроса
- задача pocketbase-storage забрала очередь себе: границы, счётчик попыток,
  состояние «мертва» и оракулы
This commit is contained in:
av
2026-08-11 14:13:27 +03:00
parent 6c996209b7
commit df65eb5e32
7 changed files with 248 additions and 20 deletions
+14 -9
View File
@@ -20,7 +20,10 @@
делят одну базу. Отдельного воркер-процесса нет намеренно.
- **Очередь таблицей.** Состояние задачи лежит в SQLite, воркер забирает работу
запросом с захватом. Внешний брокер не заводим: нагрузка — единицы записей в
день (оценка владельца, не замер: `research/` пуст).
день (оценка владельца, не замер). Готовую библиотеку очереди тоже не заводим —
решено 2026-08-11,
[ADR](adr/ADR-2026-08-11-queue-as-pocketbase-collection.md), сравнение
кандидатов в [research/job-queue.md](research/job-queue.md).
<!-- канон: поведение → openspec/specs/pipeline -->
- **Шаг конвейера идемпотентен по повтору.** Задача, брошенная на середине,
достаётся снова по истечении срока захвата и проходит шаг заново.
@@ -123,9 +126,8 @@
раскладку на диске — решено 2026-08-11,
[ADR](adr/ADR-2026-08-11-pocketbase-storage-with-admin-panel.md), замер панели
в [research/pocketbase.md](research/pocketbase.md). Требование CGO этим
снимается. Не решено, чем становится конвейер задач: таблицей PocketBase с тем
же захватом или чем-то другим — разведка `job-queue-choice`. Данные не
переносим — начинаем с чистого листа.
снимается. Чем становится конвейер задач, решено 2026-08-11 — см. «Очередь»
ниже. Данные не переносим — начинаем с чистого листа.
- **Учётные записи.** Вход через OIDC, провайдер — Authelia, а ответ провайдера
обрабатывает PocketBase, а не наш код (тот же ADR). Не решено, где живёт сессия
и как связываются пользователь Telegram и пользователь веба. Панель
@@ -166,11 +168,14 @@
сервис определяет содержимое сам, то ли часть записей теряется на этом.
- **Видео.** Дорожку из видеофайла бот принимает по MIME-типу `video/`, но
конвертер этот случай не проверялся.
- **Очередь.** Принцип «очередь таблицей» и захват `FindAndAcquire` написаны
вручную; чем именно захват несовершенен — [database.md](database.md),
«Представление данных». Не решено здесь другое: пересматривать ли модель
очереди целиком — разведка `job-queue-choice`, раньше смены хранилища, чтобы
не переписывать захват дважды.
- **Очередь.** Модель очереди решена 2026-08-11: остаётся своей таблицей и
становится коллекцией PocketBase, захват сворачивается в один запрос с
`RETURNING`, число попыток ложится колонкой, а исчерпавшая их задача переходит
в состояние «мертва» вместо `is_error = 1`
([ADR](adr/ADR-2026-08-11-queue-as-pocketbase-collection.md)). Пишет это
`pocketbase-storage` тем же заходом, что и хранилище. Не решено, отказываться
ли от холостого опроса: три воркера дают 259 200 запросов в сутки при нагрузке
в единицы записей в день, и во что это обходится, никто не мерил.
- **Наблюдаемость.** `/metrics` остаётся и развивается. Чем — дописывать
счётчики через `client_golang` или перейти на OpenTelemetry с трассировкой —
решает разведка `opentelemetry-fit`. Коллектор был бы процессом, которого в