processCatched перед Add проверяет присутствие торрента в qBittorrent (один листинг на тик): если раздача уже есть — усыновляем (promote catched→downloading без повторного Add и без LLM-namer, имя из раздачи), иначе добавляем как раньше. Это убирает бесконечный цикл дубль-Add → 409 → ретрай и лишние вызовы LLM. Инвариант приёма «одна активная на infohash» делает различие «наш/чужой» ненужным. source_type перечитывается под замком (сужение гонки апгрейда F6); при недоступности qBittorrent тик пропускается без вызова LLM. Дедуп на приёме (дубль на уже активную задачу) теперь отражается явным ответом бота «дубль уже активной #id — добавление отменено». Спека download-tracking обновлена (OpenSpec change заархивирован); закрыта задача беклога review-f2-promote-without-add. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.0 KiB
Why
Пойманная (catched) загрузка, чей торрент уже присутствует в qBittorrent
(добавлен раньше вручную/другим клиентом или прошлой попыткой jellybit), уходит в
бесконечный цикл: processCatched на каждом тике зовёт qbt.Add, qBittorrent
отбивает дубль (409 Conflict), сбой трактуется как транзиентный → задача
остаётся в catched → повтор, и на каждом безнадёжном тике впустую вызывается
LLM-namer. Диагноз: docs/backlog/review-f2-promote-without-add.md.
Решение: перед добавлением проверять присутствие торрента в qBittorrent. Раз
инвариант приёма гарантирует, что до воркера доходит лишь загрузка, для которой в
jellybit нет другой активной задачи (дубль на активную отсекается ещё на приёме),
присутствие торрента в qBittorrent означает «его надо усыновить» — довести до
downloading без повторного add и разложить, а не пытаться добавить дубль и
ловить 409.
Отдельно: повторное добавление торрента, который jellybit уже ведёт активной задачей, транспорт должен явно отражать как дубль (сообщение «добавление отменено»), а не молчаливым «уже в работе».
What Changes
- В
processCatchedпередqbt.Add— проверка присутствия торрента в qBittorrent (один листинг на тик). Присутствует →catched → downloadingбезadd(усыновление;display_nameиз имени раздачи, без LLM); нет → прежний путь добавления. Проверка — до namer, чтобы не жечь LLM. - При недоступности qBittorrent (листинг не удался) тик пропускается без вызова
LLM; предел ретрая — существующий предохранитель
catch_timeout. - Гонка апгрейда F6 сужается:
source_typeперечитывается под блокировкой переходов перед добавлением. - Транспорт Telegram на дедуп приёма (дубль на уже активную задачу) отвечает явным «дубль уже активной #id — добавление отменено» (+ лог), без создания новой записи.
Capabilities
New Capabilities
Modified Capabilities
download-tracking: требование «Добавление пойманной загрузки в qBittorrent» дополняется проверкой присутствия и усыновлением (promote без повторногоadd) при наличии торрента, перечитыванием источника под замком и пропуском тика при недоступности qBittorrent.
Impact
- Код:
internal/worker/worker.go(processCatched, presence-check, усыновление вместо повторногоadd),internal/tgbot/bot.go(текст ответа на дедуп). - Внешние вызовы: убирает лишние
qbt.Add(и 409) иchat.completions(LLM-namer) на повторах; добавляет одинqbt.Torrents-листинг на тик вprocessCatched. - Тесты:
internal/worker/catched_test.go. - БД-миграции, новых состояний, конфигурации и внешнего API — нет.