pub async fn drain_queue<R, Fut>(
repo_root: &Path,
once: bool,
run_mission: R,
) -> Result<DrainReport>Expand description
Drain the per-repo queue one mission at a time. Recover dead claims once up
front; then atomically claim the front entry with the repo-wide busy guard;
on Busy either return (once) or sleep 5s and retry; on a lost claim race,
retry after a brief sleep; on Claimed, run backend readiness under the
claim (park → finish_claim; rate-limit → release + rotate/delay; ok → run),
skip a ticket-born entry whose blocker failed, otherwise write ticket
Running, invoke the injected run_mission, then finish/release the claim,
write the terminal ticket state, and honor once.
Readiness is probed after claim so a sibling drain cannot race a peek
queue::removeinto marking a live run’s ticket Failed.
Does NOT do checkout restoration or event printing — those stay with the
caller, which is exactly why run_mission is injected rather than run
inside this core: the CLI keeps its live event tail, while a headless
caller (REST, Slack) can drive the same loop with no terminal attached.