Run torrents off the command worker

A torrent ran inline on the single sequential worker, so it blocked every
feed scan, HTTP download and status command behind it -- for up to
stall_mins waiting on metadata, and for up to seed_time_mins seeding after
finishing. A live daemon was wedged with 47 pending torrents and would not
answer a status command for 15s.

spawn_torrent detaches the job behind a 2-permit semaphore and marks the
row 'downloading' so a rescan cannot queue it twice. One-shot CLI runs
stay inline, or the process would exit mid-download.

Torrents themselves verified working: a 755 MB Debian netinst downloaded
to completion against a real swarm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
This commit is contained in:
2026-09-10 02:51:21 +00:00
parent e97f2b9c2f
commit 19309d609f
2 changed files with 115 additions and 20 deletions

View File

@@ -56,6 +56,41 @@ and until now nothing set them.
---
## 2026-09-10 — Torrents: they work, and one was freezing the whole daemon
Asked "is torrents working?". The honest answer had been "unverified since step 7" — so it got tested
properly.
**They work.** End to end against a real swarm: Debian 13.6.0 netinst, 791,674,880 bytes, completed,
`file` confirms a bootable ISO, row marked `done`. Metadata resolution, transfer, placement and
completion all good.
**But the daemon was wedged.** Ray's CT-log feed had 47 pending torrents and nothing was progressing.
The worker was blocked: a `status` command over the control socket got no reply in 15s. Torrents ran
*inline on the single command worker*, so one torrent stopped every feed scan, every HTTP download
and every status command behind it — for up to `stall_mins` (30 default) waiting on metadata, and
worse, `Torrents::fetch` blocks on seeding for up to `seed_time_mins` (60 default) **after**
finishing. One successful torrent could have frozen podcast fetching for an hour.
Torrents are now detached: `spawn_torrent` runs the job on its own task behind a 2-permit semaphore,
the row is marked `downloading` so a rescan does not queue it twice, and the worker moves straight
on. A one-shot CLI run still runs them inline, or the process would exit mid-download. Verified: the
worker now answers `status` in 0.0s.
A diagnostic misstep worth recording: `/api/settings` returning 200 was taken as proof the worker was
alive. It is not — the web server is a separate task, so HTTP stays responsive while the queue is
completely stuck. Probing the control socket is the real test.
**Those CT-log torrents are ~557 GB each, 47 of them.** The RSS advertises `length="0"`, so nothing
warns you; the size only appears once metadata resolves. `auto_download` on that feed is set to
false as a hold, since restarting would otherwise have begun a half-terabyte transfer immediately
(the scheduler's first tick fires at startup). Flip it back in the feed's Settings when wanted.
Also noted: an aborted torrent leaves librqbit's pre-created file placeholders behind in the
destination folder (zero-length). Not cleaned up yet.
---
## 2026-09-10 — Schedule pickers, and progress painting every row
**Pickers.** "Check feeds every" is a number input plus a unit dropdown (minutes/hours/days/weeks)