From 48ed7be5d94166d676c7285b6c6b27b37470c416 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Fri, 1 May 2026 14:33:45 +0000 Subject: [PATCH] libraries: initial availability sweep before watcher's first sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit new_health_map seeds every library as Online, and the watcher's tick loop sleeps WATCH_QUICK_INTERVAL_SECONDS (default 60s) before its first probe — meaning /libraries reported the optimistic default for up to a minute after boot, even when a share was clearly unmounted. Run the same refresh_health pass once at the top of the watcher thread before entering the sleep loop. /libraries is then truthful within milliseconds of the watcher thread starting (effectively from the first HTTP request, since the watcher spawns well before the server binds). The per-tick gate inside the loop is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main.rs b/src/main.rs index 7a2d0b9..93df054 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1945,6 +1945,24 @@ fn watch_files( let mut last_full_scan = SystemTime::now(); let mut scan_count = 0u64; + // Initial availability sweep before the loop's first sleep so + // /libraries reports the truth from the very first request, + // rather than the optimistic Online default that + // new_health_map seeds. Without this, an unmounted share would + // appear online for up to WATCH_QUICK_INTERVAL_SECONDS (default + // 60s) after boot. Same probe logic as the per-tick gate + // below; no ingest runs here, just the health update + log. + for lib in &libs { + let context = opentelemetry::Context::new(); + let had_data = exif_dao + .lock() + .expect("exif_dao poisoned") + .count_for_library(&context, lib.id) + .map(|n| n > 0) + .unwrap_or(false); + libraries::refresh_health(&library_health, lib, had_data); + } + loop { std::thread::sleep(Duration::from_secs(quick_interval_secs));