fix: scheduler next_run accounts for elapsed time since last cycle
On restart the scheduler was counting interval_hours from now, ignoring when the last cycle actually ran. It now reads last_run_at (in-memory or DB) and deducts elapsed time so a restart doesn't silently push the next fire by a full interval. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1870,11 +1870,30 @@ def _scheduler_loop(stop_event: threading.Event):
|
||||
_current_status["interval_hours"] = interval_hours
|
||||
logger.info(f"[Scheduler] Weekend — prochain cycle à {next_slot.strftime('%H:%M')} UTC ({wait_secs/3600:.1f}h)")
|
||||
else:
|
||||
wait_secs = interval_hours * 3600
|
||||
next_run = now_utc + timedelta(hours=interval_hours)
|
||||
# Account for time already elapsed since last cycle so a restart
|
||||
# doesn't reset the countdown — fire as soon as the interval is due.
|
||||
last_run_iso = _current_status.get("last_run_at")
|
||||
if not last_run_iso:
|
||||
# Also check DB for the most recent completed run
|
||||
try:
|
||||
from services.database import get_cycle_runs
|
||||
recent = get_cycle_runs(limit=1)
|
||||
if recent:
|
||||
last_run_iso = recent[0].get("created_at") or recent[0].get("run_id", "")[:19].replace("T", " ")
|
||||
except Exception:
|
||||
pass
|
||||
elapsed_secs = 0.0
|
||||
if last_run_iso:
|
||||
try:
|
||||
last_dt = datetime.fromisoformat(last_run_iso.replace(" ", "T").rstrip("Z"))
|
||||
elapsed_secs = (now_utc - last_dt).total_seconds()
|
||||
except Exception:
|
||||
pass
|
||||
wait_secs = max(60, interval_hours * 3600 - elapsed_secs)
|
||||
next_run = now_utc + timedelta(seconds=wait_secs)
|
||||
_current_status["next_run_at"] = next_run.isoformat()
|
||||
_current_status["interval_hours"] = interval_hours
|
||||
logger.info(f"[Scheduler] Prochain cycle dans {interval_hours}h ({next_run.strftime('%H:%M')} UTC)")
|
||||
logger.info(f"[Scheduler] Prochain cycle dans {wait_secs/3600:.1f}h ({next_run.strftime('%H:%M')} UTC) — elapsed since last: {elapsed_secs/3600:.1f}h")
|
||||
|
||||
stop_event.wait(timeout=wait_secs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user