docs: решено оставить очередь своей таблицей коллекцией PocketBase
- заведены записка разведки job-queue-choice и ADR: готовые библиотеки River и goqite отвергнуты, захват сворачивается в один запрос с RETURNING - в architecture.md уточнён принцип «очередь таблицей» и закрыт открытый вопрос «Очередь», кроме холостого опроса - задача pocketbase-storage забрала очередь себе: границы, счётчик попыток, состояние «мертва» и оракулы
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@
|
||||
- [🐞 Убирать записанный файл, когда приём отказал на середине](items/orphan-file-on-failed-intake.md) — Отказ чтения метаданных и отказ записи на диск оставляют файл в каталоге хранения без задачи и без учёта: сопоставить его не с чем, удалять приходится руками.
|
||||
- [🧹 Задать таймауты обращениям к внешним сервисам](items/external-call-timeouts.md) — Ни у Telegram, ни у Object Storage, ни у SpeechKit нет таймаута: молчащий собеседник держит шаг конвейера до истечения часового захвата.
|
||||
- [🔬 Очередь задач: своя таблица или готовая библиотека](items/job-queue-choice.md) — Очередь написана вручную: захват двумя запросами без транзакции, протухание временем, опрос раз в секунду вхолостую тремя воркерами.
|
||||
- [🧹 Перевести хранилище и файлы записей на встроенный PocketBase](items/pocketbase-storage.md) — Записи, метаданные и файлы лежат порознь, и владелец не видит их ничем, кроме консоли на сервере: панель PocketBase покажет и то и другое, только если они переедут к ней.
|
||||
- [🧹 Перевести хранилище и файлы записей на встроенный PocketBase](items/pocketbase-storage.md) — Записи, метаданные и файлы лежат порознь, и владелец не видит их ничем, кроме консоли на сервере: панель PocketBase покажет их, только если они переедут к ней. Заодно переписывается захват задачи: сегодня это два запроса без транзакции, а падающая всегда задача падает вечно.
|
||||
- [✨ Пускать в приложение только после входа через OIDC](items/oidc-login.md) — HTTP API открыт наружу без аутентификации: любой из интернета заводит задачи за наши деньги и читает чужие расшифровки по идентификатору.
|
||||
- [✨ Привязать запись к владельцу и отдавать только свои](items/record-ownership.md) — У задачи и файла нет владельца, поэтому знание UUID задачи и есть право её читать.
|
||||
- [✨ Сопоставить пользователя Telegram с учётной записью](items/telegram-account-link.md) — Белый список сверяется с именем пользователя Telegram, которое владелец меняет в любой момент, а записи из бота ни с кем не связаны.
|
||||
|
||||
@@ -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