From ba038a3af61a9d5956a6522ea79dea1107396ccd Mon Sep 17 00:00:00 2001 From: oliver Date: Tue, 4 Aug 2026 21:56:01 +0800 Subject: [PATCH] Refresh Fabric KPIs live while an LLDP collect job is running. Co-authored-by: Cursor --- netx_api/lldp_collect_service.py | 11 ++++++++++- netx_api/topology_discover_jobs.py | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/netx_api/lldp_collect_service.py b/netx_api/lldp_collect_service.py index d58f35d..eec6504 100644 --- a/netx_api/lldp_collect_service.py +++ b/netx_api/lldp_collect_service.py @@ -20,6 +20,7 @@ from .topology_service import ( get_discover_job, prune_discover_jobs, reclaim_stale_discover_jobs, + refresh_fabric_stats, start_discover_job, ) @@ -256,8 +257,16 @@ def start_collect(db: Session, *, trigger_mode: str = "manual") -> dict: def get_dashboard(db: Session) -> LldpCollectDashboardOut: policy = ensure_policy(db) - stats = db.get(TopoFabricStats, "global") running = has_running_job(db) + # While a collect job is writing Fabric, refresh KPIs from live tables so the + # board tracks mid-job growth (job.edges_added already moves; cached stats did not). + # Missing marks are still applied only at job end — stale/missing may lag until then. + if running is not None: + stats = refresh_fabric_stats(db) + else: + stats = db.get(TopoFabricStats, "global") + if stats is None: + stats = refresh_fabric_stats(db) last = last_finished_job(db) return LldpCollectDashboardOut( policy=_policy_out(policy), diff --git a/netx_api/topology_discover_jobs.py b/netx_api/topology_discover_jobs.py index 5c0f037..7b7a6aa 100644 --- a/netx_api/topology_discover_jobs.py +++ b/netx_api/topology_discover_jobs.py @@ -111,6 +111,12 @@ def _run_discover_job(job_id: str, body: FabricDiscoverRequest) -> None: job.edges_updated = updated job.updated_at = _utcnow() db.commit() + # Keep Fabric KPI cache roughly in sync during long runs (dashboard polls job). + if int(job.done or 0) % 50 == 0: + try: + refresh_fabric_stats(db) + except Exception: # noqa: BLE001 + db.rollback() # Absent on a successfully scanned endpoint → missing; purge after N cycles. if scanned_ok: