Быстрый приём: сохранение в catched, добавление в qBittorrent — шаг worker'а
Приём (Ingest) стал быстрым: синхронно только парс magnet, синтез контекста из полей ссылки, атомарный дедуп и запись загрузки в новое состояние `catched` — ответ клиенту сразу. Медленный вывод имени (LLM) и добавление в qBittorrent вынесены в асинхронный шаг машины состояний, который двигает worker. - store: состояние `catched` (нетерминальное, активная группа); атомарный переход PromoteCatched (catched → downloading + display_name) с гардом state='catched' (ре-валидация после сетевых вызовов вне блокировки) - ingest: убраны namer/qbt из пути приёма; пишем `catched`, отвечаем сразу - worker.processCatched: вне w.mu выводит имя и qbt.Add, под w.mu — короткий переход; сбой add оставляет catched (ретрай тиком); предохранитель catch_timeout → failed(qbit_add)+notify; catched исключён из проверок пропажи - config: worker.catch_timeout (дефолт 10m) - веб-UI: бейдж catched, активная группа, самозавершающийся htmx-поллинг карточки/страницы до перехода в downloading; Telegram-текст без сырого catched - OpenSpec: дельты ingest/download-tracking/web-ui влиты в спеки, change заархивирован Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -80,13 +80,13 @@ func runServe(args []string) error {
|
||||
}
|
||||
|
||||
// Вывод отображаемого имени торрента из контекста (best-effort). Без LLM
|
||||
// работает только алгоритмический фолбек.
|
||||
// работает только алгоритмический фолбек. Namer зовёт worker на шаге
|
||||
// добавления пойманной загрузки (не синхронный приём).
|
||||
namer := naming.New(llmProvider, cfg.LLM.MaxRetries, logger)
|
||||
|
||||
ingestor := ingest.New(st, qb, namer, ingest.Config{
|
||||
Category: cfg.QBittorrent.Category,
|
||||
SavePath: cfg.QBittorrent.SavePath,
|
||||
}, logger)
|
||||
// Быстрый приём: сохраняет загрузку в catched и сразу отвечает; добавление в
|
||||
// qBittorrent и вывод имени делает worker (см. download-tracking).
|
||||
ingestor := ingest.New(st, logger)
|
||||
|
||||
// Ф4: базы метаданных (опц.). Без них авто-раскладки нет — всё в review.
|
||||
providers, err := metadataProviders(cfg, logger)
|
||||
@@ -126,8 +126,11 @@ func runServe(args []string) error {
|
||||
PollInterval: cfg.Worker.PollInterval.Std(),
|
||||
StuckAfter: cfg.Worker.StuckAfter.Std(),
|
||||
MagnetTimeout: cfg.Worker.MagnetTimeout.Std(),
|
||||
CatchTimeout: cfg.Worker.CatchTimeout.Std(),
|
||||
SourceMissingThreshold: cfg.Worker.SourceMissingThreshold,
|
||||
}, logger)
|
||||
// Вывод имени на шаге добавления пойманной загрузки (best-effort).
|
||||
wrk.SetNamer(namer)
|
||||
|
||||
// Пересканирование Jellyfin после раскладки (опц.). Недоступность Jellyfin
|
||||
// не валит сервис — скан просто не сработает (залогируется в воркере).
|
||||
@@ -188,10 +191,6 @@ func runServe(args []string) error {
|
||||
WebBaseURL: cfg.Telegram.WebBaseURL,
|
||||
}, logger)
|
||||
wrk.SetNotifier(bot)
|
||||
// Приёмные падения (qbit_add) минуют worker — уведомляем напрямую.
|
||||
ingestor.SetFailureNotifier(func(id string) {
|
||||
bot.Notify(context.Background(), id, worker.EventFailed)
|
||||
})
|
||||
go bot.Run(ctx)
|
||||
logger.Info("telegram bot enabled",
|
||||
"bot", api.Self.UserName, "allowed_users", len(cfg.Telegram.AllowedUserIDs))
|
||||
|
||||
Reference in New Issue
Block a user