feat(scheduler): admin-editable job intervals (DB-backed, live reschedule)
Add scheduler_settings (per-job interval override, migration 0015) and a
PATCH /api/admin/scheduler/jobs/{id} that persists the override and live-
reschedules the running APScheduler job. Intervals load from the DB (env
defaults as fallback); the snapshot reports the live trigger interval.
This commit is contained in:
parent
b71d07c098
commit
84aebe16c7
4 changed files with 126 additions and 41 deletions
|
|
@ -1,7 +1,7 @@
|
|||
"""Admin Scheduler dashboard: a live view of what the background scheduler is doing —
|
||||
per-job run activity (from the in-process scheduler), the work still queued (DB-derived),
|
||||
and the shared quota picture."""
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy import and_, func, or_, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
|
@ -10,12 +10,36 @@ from app.config import settings
|
|||
from app.db import get_db
|
||||
from app.models import Channel, Subscription, User, Video
|
||||
from app.routes.admin import admin_user
|
||||
from app.scheduler import scheduler_snapshot
|
||||
from app.scheduler import JOB_INTERVALS, MAX_INTERVAL, MIN_INTERVAL, apply_interval, scheduler_snapshot
|
||||
from app.sync.runner import estimate_deep_backfill
|
||||
|
||||
router = APIRouter(prefix="/api/admin/scheduler", tags=["admin"])
|
||||
|
||||
|
||||
@router.patch("/jobs/{job_id}")
|
||||
def set_job_interval(
|
||||
job_id: str,
|
||||
payload: dict,
|
||||
_: User = Depends(admin_user),
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
"""Change how often a scheduler job runs (minutes). Persisted as an override and applied
|
||||
to the live scheduler immediately."""
|
||||
if job_id not in JOB_INTERVALS:
|
||||
raise HTTPException(status_code=404, detail="Unknown job")
|
||||
try:
|
||||
minutes = int(payload.get("interval_minutes"))
|
||||
except (TypeError, ValueError):
|
||||
raise HTTPException(status_code=400, detail="interval_minutes must be a number")
|
||||
if not (MIN_INTERVAL <= minutes <= MAX_INTERVAL):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"interval must be between {MIN_INTERVAL} and {MAX_INTERVAL} minutes",
|
||||
)
|
||||
applied = apply_interval(db, job_id, minutes)
|
||||
return {"id": job_id, "interval_minutes": applied}
|
||||
|
||||
|
||||
@router.get("")
|
||||
def get_scheduler(
|
||||
_: User = Depends(admin_user), db: Session = Depends(get_db)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue