""" Runs once at app startup: - Marks tasks stuck in 'running' with stale heartbeat as 'stale'. These are tasks that were running when the app last crashed or restarted. """ from datetime import datetime, timedelta, timezone from sqlalchemy import update from app.models.task import Task from app.services.database import AsyncSessionLocal STALE_AFTER_MINUTES = 15 async def recover_stale_tasks() -> int: cutoff = datetime.now(timezone.utc) - timedelta(minutes=STALE_AFTER_MINUTES) async with AsyncSessionLocal() as db: async with db.begin(): result = await db.execute( update(Task) .where(Task.status == "running", Task.started_at < cutoff) .values(status="stale") .returning(Task.id) ) stale_ids = result.scalars().all() if stale_ids: print(f"[startup] Marked {len(stale_ids)} stale task(s): {stale_ids}") return len(stale_ids)