Refactor: Track analysis jobs via InFlight struct

This commit replaces the disk-based `analysis_input.json` marker for
in-progress analysis jobs with an in-memory
`Arc<RwLock<HashSet<PathBuf>>>`.

Previously, the existence of `analysis_input.json` was used as a signal
that a case was queued or being analyzed. This led to stale "Queued"
states after server restarts, as the disk file would persist while the
server process tracking it had vanished.

The new `InFlight` struct, held in `AppState`, provides a process-local
marker. This ensures that:

- Server restarts correctly reset the state, as the `HashSet` is
  cleared.
- Race conditions for triggering analysis are handled by the `try_claim`
  method, replacing the previous reliance on file system `O_EXCL` flags.
- The `AnalyzeJob` payload now travels with the job over the channel,
  eliminating the need for workers to re-read `analysis_input.json` from
  disk.

This change simplifies state management and improves the reliability of
analysis job tracking.
This commit is contained in:
2026-05-05 20:01:07 +02:00
parent e0cfd5d512
commit 76bf65be1a
15 changed files with 704 additions and 336 deletions
+5
View File
@@ -190,10 +190,12 @@ async fn main() {
let (analyze_tx, analyze_rx) = analyze::channel();
let analyze_busy: doctate_server::WorkerBusy =
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let analyze_in_flight = analyze::InFlight::new();
tokio::spawn(analyze::worker::run(
analyze_rx,
http_client.clone(),
analyze_busy.clone(),
analyze_in_flight.clone(),
vocab.clone(),
events_tx.clone(),
));
@@ -201,12 +203,14 @@ async fn main() {
{
let data_path = config.data_path.clone();
let idle_threshold = std::time::Duration::from_secs(config.analysis_idle_threshold_secs);
let in_flight = analyze_in_flight.clone();
tokio::spawn(async move {
analyze::recovery::boot_scan_state(
&data_path,
idle_threshold,
std::time::SystemTime::now(),
server_boot_time,
&in_flight,
)
.await;
});
@@ -227,6 +231,7 @@ async fn main() {
http_client,
vocab,
boot_time: doctate_server::BootTime(server_boot_time),
analyze_in_flight,
};
let addr = format!("0.0.0.0:{}", config.server_port);