fix: decouple oneliner-heal from request handler tasks
heal_orphans_if_idle called regenerate_missing_oneliners_for_user inline on the request task, blocking the browser for up to N×60s when orphans existed (observed with 16 cases after manual cleanup). Now: CAS on new OnelinerHealBusy flag + tokio::spawn + BusyGuard reset-on-drop. Handler returns immediately; the existing OnelinerUpdated SSE event delivers results via the usual reload. Startup recovery shares the flag so a concurrent page-load during boot cannot fire a parallel regen loop against Ollama. Regression test uses wiremock + timeout(150ms) + .expect(5) to verify both non-blocking return and dedup of parallel invocations.
This commit is contained in:
@@ -116,6 +116,12 @@ async fn main() {
|
||||
// subscribed browsers.
|
||||
let events_tx = events::channel();
|
||||
|
||||
// Dedup flag shared by the startup oneliner-regen task and every
|
||||
// request-driven `heal_orphans_if_idle` spawn. One-at-a-time semantics
|
||||
// keep Ollama from seeing overlapping regen loops.
|
||||
let oneliner_heal_busy: doctate_server::WorkerBusy =
|
||||
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
|
||||
// Transcription pipeline: channel + worker + recovery scan.
|
||||
let (transcribe_tx, transcribe_rx) = transcribe::channel();
|
||||
let transcribe_busy: doctate_server::WorkerBusy =
|
||||
@@ -135,10 +141,14 @@ async fn main() {
|
||||
let cfg = config.clone();
|
||||
let vocab = vocab.clone();
|
||||
let events = events_tx.clone();
|
||||
let heal_busy = oneliner_heal_busy.clone();
|
||||
tokio::spawn(async move {
|
||||
transcribe::recovery::scan_and_enqueue(&data_path, &tx).await;
|
||||
// Then catch up oneliners for cases that crashed between
|
||||
// transcript-write and oneliner-write in a previous run.
|
||||
// Hold the shared heal-busy flag while running so a concurrent
|
||||
// page-load does not spawn a second parallel regen loop.
|
||||
let _guard = doctate_server::BusyGuard::new(heal_busy);
|
||||
transcribe::recovery::regenerate_missing_oneliners(
|
||||
&data_path, &client, &cfg, &vocab, &events,
|
||||
)
|
||||
@@ -174,6 +184,7 @@ async fn main() {
|
||||
magic_link_store: doctate_server::magic_link::new_store(),
|
||||
analyze_busy: doctate_server::AnalyzeBusy(analyze_busy),
|
||||
transcribe_busy: doctate_server::TranscribeBusy(transcribe_busy),
|
||||
oneliner_heal_busy: doctate_server::OnelinerHealBusy(oneliner_heal_busy),
|
||||
events_tx,
|
||||
http_client,
|
||||
vocab,
|
||||
|
||||
Reference in New Issue
Block a user