fix(lore): report a lost enqueue instead of wedging at pending (#413) #459
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/413-lore-enqueue-wedge"
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?
Closes #413 (LOW). Also closes the last of #416's cross-referenced stuck states that is purely backend.
The defect
lore_generation_statusis committed aspendingand then the Celery task is enqueued. The broker is deliberately configured to fail fast — 2s timeouts,retry_on_timeout: False— so an unreachable broker is a routine event, not an edge case. The commit lands, nothing is queued, and the session shows "Lore generation queued…" with no work behind it. The endpoint's own guard then treats that ghost as a live run and refuses to re-trigger.Reachable from two independent call sites: the GM-facing endpoint, and the
on_session_summary_availablefan-out afterprocess_audio(where_safe_delayswallowed the exception entirely).Deliberately not the reorder the issue proposes
The issue asks that
pendingbe set only after a successful enqueue. That introduces a race:generate_lore_proposalsdoes not requirependingon pickup — it loads the session and proceeds. Enqueueing before the commit lets a fast worker setextracting, which the laterpendingcommit then overwrites. That trades a visible wedge for a silent one, in a milestone about not losing state.Marking
failedon the way out is the same repair without the race:failedwith a plain explanation and returns 503, so the caller learns the click did nothing rather than getting a 202 for work that was never queued._safe_delaynow returns whether the enqueue landed, andprocess_audiomarks lorefailedwhen it did not. Swallowing remains correct for the tasks whose absence changes no stored state; it was only ever wrong for the one whose status the caller had already committed as queued.failedspecifically, because that is the state the retry paths accept — so the re-run button is back immediately, rather than after #416's 30-minute staleness threshold or #398's 8-hour watchdog. Both remain as backstops; this is the fast path.Worth noting: the issue's severity has already dropped
When #413 was filed, the stated consequence was "The only fix is a manual database update." That is no longer true — #416 added a staleness threshold that lets a GM supersede a stalled run after 30 minutes, and #398's watchdog flips it to
failedafter 8 hours. This PR turns "wait 30 minutes" into "told at once", which is the remaining gap rather than the original one.Verification
Mutation-checked: with the fix reverted, 5 of 6 tests fail.
One test exists specifically to stop this change regressing in the other direction —
_safe_delayswallows so that one broker hiccup cannot block the other fan-out enqueues, and that behaviour is now pinned. Making the fan-out raise would be an easy "cleanup" for someone to attempt later.1,476 backend tests pass (was 1,470). Lint clean at pinned ruff 0.4.4.
🤖 Generated with Claude Code