Живые обновления прогресса и раздел «Раздача» (live-status)
Воркер ведёт in-memory снимок телеметрии раздач (прогресс, скорость, ETA, рейтинг, сиды/пиры, отдано) под отдельным RWMutex, обновляя его на каждом тике поллинга сразу после построения byHash — без лишних вызовов qBittorrent и без хранения в БД (волатильно). qbt.Torrent дополнен полями телеметрии. Веб-UI читает снимок через узкий контракт LiveStatus: карточки активных загрузок показывают живой прогресс-бар (htmx-поллинг фрагмента every 3s, точечно — без сброса фильтров), на странице загрузки появилась секция «Раздача» для сидирующих задач. Начальный кадр рендерится сразу со значениями; при отсутствии данных UI деградирует штатно. Капабилити live-status (OpenSpec), web-ui дополнен. Change заархивирован. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
## 1. Телеметрия в клиенте qBittorrent
|
||||
|
||||
- [x] 1.1 Добавить в `qbt.Torrent` поля `Dlspeed`, `Eta`, `Ratio`, `NumSeeds`,
|
||||
`NumLeechs`, `Uploaded`, `Upspeed` с json-тегами из `/torrents/info`
|
||||
(`dlspeed`, `eta`, `ratio`, `num_seeds`, `num_leechs`, `uploaded`, `upspeed`)
|
||||
- [x] 1.2 Обновить комментарий-доку `Torrent` (подмножество полей расширено)
|
||||
|
||||
## 2. Снимок телеметрии в воркере
|
||||
|
||||
- [x] 2.1 Добавить тип `worker.Live{Progress, DlSpeed, ETA, State, Seeding,
|
||||
Ratio, Seeds, Peers, Uploaded, UpSpeed}` (курированный, без зависимости на
|
||||
qbt у читателей); `Seeding` вычислять через `classify(state) == classReady`
|
||||
- [x] 2.2 Добавить в `Worker` поле снимка `live map[string]Live` + отдельный
|
||||
`sync.RWMutex` (не `w.mu`); инициализация в `New`
|
||||
- [x] 2.3 В `Poll` собрать новую карту из полученного `torrents` — **три ключа
|
||||
на торрент** (lowercase `Hash`/`InfohashV1`/`InfohashV2`, как `byHash`) — и
|
||||
атомарно подменить снимок **сразу после построения `byHash`, до store-
|
||||
операций** (телеметрия обновляется даже при последующем сбое reconcile)
|
||||
- [x] 2.4 Реализовать `Live(infohash string) (Live, bool)` — чтение под RLock,
|
||||
`ok=false` при пустом/неизвестном infohash
|
||||
- [x] 2.5 Тесты: снимок обновляется после `Poll`; `Live` отдаёт данные
|
||||
качающейся и сидирующей задачи (с верным `Seeding`); поиск по любому из трёх
|
||||
хэшей; неизвестный/пустой infohash → `ok=false`
|
||||
|
||||
## 3. Транспорт: контракт и фрагмент-роуты
|
||||
|
||||
- [x] 3.1 Объявить интерфейс `LiveStatus` в `internal/httpapi` и добавить поле
|
||||
`Live LiveStatus` в `Deps`
|
||||
- [x] 3.2 Прокинуть `Live: wrk` в `httpapi.Deps` в `cmd/jellybit/serve.go`
|
||||
- [x] 3.3 Добавить роуты `GET /fragments/downloads/{id}/progress` и
|
||||
`GET /fragments/downloads/{id}/seeding` в `NewRouter`
|
||||
- [x] 3.4 Реализовать обработчики фрагментов: `GetDownload` → infohash/состояние
|
||||
+ `Live(infohash)`; рендер партиала; `ok=false` → деградация без живых значений
|
||||
- [x] 3.5 **Начальный рендер со значениями:** расширить `downloadView` и
|
||||
`downloadDetailView` полями телеметрии; в `handleIndex`/`handleDownload`
|
||||
вызвать `Live(infohash)` для нужных задач и положить во view — одна модель для
|
||||
страницы и для фрагмент-роута (без мигания при первой загрузке)
|
||||
- [x] 3.6 Добавить хелперы форматирования скорости/размера/ETA: человекочитаемые
|
||||
единицы (байты→КиБ/МиБ, скорость/с), sentinel'ы qBittorrent (`eta=8640000`→
|
||||
«—»/«∞», `ratio<0`→«—»); зафиксировать выбор `num_seeds`/`num_leechs`
|
||||
|
||||
## 4. Шаблоны и живое обновление
|
||||
|
||||
- [x] 4.1 Партиал `partials/progress.html` (прогресс-бар + скорость + ETA);
|
||||
включить его в карточку `index.html` для активных загрузок
|
||||
- [x] 4.2 Навесить на прогресс-блок активной карточки `hx-get` /
|
||||
`hx-trigger="every 3s"` / `hx-swap="outerHTML"`; при выходе из downloading
|
||||
фрагмент не содержит атрибутов поллинга (поллинг прекращается)
|
||||
- [x] 4.3 Партиал `partials/seeding.html` (рейтинг, сиды/пиры, отдано, скорость
|
||||
отдачи); секция «Раздача» в `download.html` для сидирующих задач, с
|
||||
htmx-поллингом и деградацией при отсутствии данных
|
||||
- [x] 4.4 Проверить, что фоновое обновление не сбрасывает фильтр/поиск/прокрутку
|
||||
на главной (поллинг точечный, на уровне карточки)
|
||||
- [x] 4.5 При необходимости — стили прогресс-бара/раздачи в `jellybit.css`
|
||||
(использовать существующие токены, без инлайн-хардкода цветов)
|
||||
|
||||
## 5. Проверки и ревью
|
||||
|
||||
- [x] 5.1 `task test` (включая новые тесты воркера и httpapi-рендера фрагментов;
|
||||
в т.ч. тест «фрагмент при выходе из downloading отдаётся без htmx-атрибутов
|
||||
поллинга»)
|
||||
- [x] 5.2 `task lint`, `gofmt`, `openspec validate --strict`
|
||||
- [x] 5.3 Ревью кода (второй чекпоинт) перед archive: соответствие спекам и
|
||||
конвенциям (логирование без секретов, ошибки `%w`, отдельный RWMutex)
|
||||
Reference in New Issue
Block a user