Smooth rate/ETA over 30-min rolling window instead of single snapshot
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -202,14 +202,25 @@ def main() -> None:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Rolling rate: keep up to 60 snapshots; compute rate from the oldest
|
||||||
|
# snapshot within the last 30 minutes for a smoothed estimate.
|
||||||
|
snapshots: list[dict] = cache.get("snapshots", [])
|
||||||
|
# Prune snapshots older than 30 minutes, but keep at least one
|
||||||
|
cutoff = now.timestamp() - 1800
|
||||||
|
recent = [s for s in snapshots if s.get("ts", 0) >= cutoff]
|
||||||
|
if not recent and snapshots:
|
||||||
|
recent = [snapshots[-1]] # always keep one for continuity
|
||||||
|
|
||||||
rate_per_sec: float | None = None
|
rate_per_sec: float | None = None
|
||||||
prev_ts = _parse_dt(cache.get("timestamp", ""))
|
rate_window_str = ""
|
||||||
prev_proc = cache.get("processed")
|
if recent:
|
||||||
if prev_ts and prev_proc is not None:
|
oldest = recent[0]
|
||||||
dt = (now - prev_ts).total_seconds()
|
dt = now.timestamp() - oldest["ts"]
|
||||||
dp = processed - int(prev_proc)
|
dp = processed - oldest["proc"]
|
||||||
if dt >= 60 and dp > 0:
|
if dt >= 60 and dp > 0:
|
||||||
rate_per_sec = dp / dt
|
rate_per_sec = dp / dt
|
||||||
|
window_min = dt / 60
|
||||||
|
rate_window_str = f"{window_min:.0f}-min avg"
|
||||||
|
|
||||||
# --- Disk space ---
|
# --- Disk space ---
|
||||||
mean_bytes: float | None = None
|
mean_bytes: float | None = None
|
||||||
@@ -225,7 +236,10 @@ def main() -> None:
|
|||||||
dl_bytes = downloaded * mean_bytes
|
dl_bytes = downloaded * mean_bytes
|
||||||
rem_bytes = _expected_remaining(pending_rows) * mean_bytes
|
rem_bytes = _expected_remaining(pending_rows) * mean_bytes
|
||||||
|
|
||||||
# Update cache
|
# Update cache: append new snapshot, keep last 60
|
||||||
|
recent.append({"ts": now.timestamp(), "proc": processed})
|
||||||
|
cache["snapshots"] = recent[-60:]
|
||||||
|
# Keep legacy keys for backwards compat
|
||||||
cache["timestamp"] = now.isoformat()
|
cache["timestamp"] = now.isoformat()
|
||||||
cache["processed"] = processed
|
cache["processed"] = processed
|
||||||
try:
|
try:
|
||||||
@@ -235,7 +249,7 @@ def main() -> None:
|
|||||||
|
|
||||||
rate_str = eta_str = ""
|
rate_str = eta_str = ""
|
||||||
if rate_per_sec and rate_per_sec > 0:
|
if rate_per_sec and rate_per_sec > 0:
|
||||||
rate_str = f"{rate_per_sec * 3600:,.0f} scans/hr"
|
rate_str = f"{rate_per_sec * 3600:,.0f} scans/hr ({rate_window_str})"
|
||||||
eta_str = _fmt_duration(pending / rate_per_sec)
|
eta_str = _fmt_duration(pending / rate_per_sec)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user