|
|
@@ -18,6 +18,7 @@
|
|
|
|
|
|
use crate::config::Config;
|
|
|
use crate::report::collect;
|
|
|
+use crate::report::repo_cache;
|
|
|
use axum::{
|
|
|
Router,
|
|
|
extract::Path,
|
|
|
@@ -105,7 +106,14 @@ pub(crate) async fn refresh_loop(
|
|
|
}
|
|
|
}
|
|
|
let mut last = String::new();
|
|
|
- let mut rows: Vec<crate::report::ReportRow> = Vec::new();
|
|
|
+ // Seed: merge the cache and collect once up front, so a freshly started
|
|
|
+ // dashboard is correct immediately instead of after the first keepalive.
|
|
|
+ repo_cache::merge_roots(&mut cfg);
|
|
|
+ let mut rows: Vec<crate::report::ReportRow> = collect(&cfg, archived);
|
|
|
+ if !rows.is_empty() {
|
|
|
+ last = serde_json::to_string(&rows).unwrap_or_default();
|
|
|
+ let _ = tx.send(last.clone());
|
|
|
+ }
|
|
|
let mut fleet: Option<crate::web::events::Snapshot> = None;
|
|
|
// ts of the fleet snapshot the rows were last reconciled against
|
|
|
let mut hull_ts: Option<u64> = None;
|
|
|
@@ -164,15 +172,7 @@ pub(crate) async fn refresh_loop(
|
|
|
// A repo cloned since the last tick (manual sync, the add-on's
|
|
|
// background loop, a first boot whose sync failed) must become
|
|
|
// visible without a restart: watch it and re-collect.
|
|
|
- let mut dirs_changed = false;
|
|
|
- for root in crate::recipe_repos::cached_roots() {
|
|
|
- let src = root.join("recipes").display().to_string();
|
|
|
- if !cfg.recipe_sources.contains(&src) {
|
|
|
- cfg.recipe_sources.push(src);
|
|
|
- cfg.docker_image_sources.push(root.display().to_string());
|
|
|
- dirs_changed = true;
|
|
|
- }
|
|
|
- }
|
|
|
+ let mut dirs_changed = repo_cache::merge_roots(&mut cfg);
|
|
|
for dir in crate::config::watchable_recipe_dirs(&cfg) {
|
|
|
if watched.contains(&dir) {
|
|
|
continue;
|