30 lines
974 B
Python
30 lines
974 B
Python
"""
|
|
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)
|