Prevent tagging from making the service unavailable #9
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
While a large auto-tagging job is active,
https://redview.nimmog.ukintermittently shows Pangolin's “No available server” page. Redview remains running; the tunnel marks target 55 unhealthy becauseGET http://localhost:3210/healthexceeds its timeout.Observed on Lyra
redview.servicedid not restart or crash.Likely mechanism
routes/tags.jshandles each JSON line fromtagger.pyby synchronously runningbetter-sqlite3writes, including a transaction containing one insert per generated tag. These writes run on the Node event loop. During active tagging, this can delay otherwise trivial requests such as/healthlong enough for Newt to remove the target from its available-server pool.Requested change
Ensure that active tagging cannot make the HTTP service fail health checks. A solution should avoid long synchronous SQLite work on the request/event-loop path—for example, batch/defer tag-result persistence with regular yields, or move persistence to a worker.
Acceptance criteria
/healthremains responsive within the Newt health-check timeout throughout a large tag scan.Fixed in
57c3fa3.Root cause: each tagger.py stdout line ran its own synchronous better-sqlite3 transaction on the event loop; sustained ingestion starved /health past Newt's timeout.
Change: tag results are queued in memory and flushed in bounded chunks (2000 rows/tx) every 250ms or at 5000 rows, with setImmediate yields between chunks; the job finalizes by draining the queue before status/marker updates, so close/error/cancel/restart semantics are preserved. Also fixed the same class of problem in purge paths: whole-subreddit/poster/tag archives are now chunked (500 rows/tx with yields), and PATCH /api/media/:id uses async unlink.
A/B on identical workload (1500 images x 40 tags): max /health latency 357ms -> 86ms, job wall time 1886ms -> 875ms. Purge of a 5000-media subreddit (200k cascaded tag deletes): 521ms stall -> bounded ~100ms chunks.
Regression tests: tests/tags-ingest-health.test.js (health latency budget during sustained ingestion, cancel flush, error tagging, hung-tagger flush) and tests/blocked-purge-health.test.js (health budget during a 5000-media purge, chunked tag-purge correctness, single-delete archive). Both fail against the pre-fix code. Full suite: 76/76 pass.