fix: reschedule APScheduler job immediately when status check interval is updated

Interval was read once at startup — changing it via API had no effect
until server restart. Now calls reschedule_status_checks() after saving.
This commit is contained in:
Pouzor
2026-03-30 23:55:38 +02:00
parent 7071f8ef5a
commit e7fc091701
3 changed files with 28 additions and 0 deletions
+2
View File
@@ -8,6 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import get_current_user from app.api.deps import get_current_user
from app.core.config import settings from app.core.config import settings
from app.core.scheduler import reschedule_status_checks
from app.db.database import AsyncSessionLocal, get_db from app.db.database import AsyncSessionLocal, get_db
from app.db.models import Node, PendingDevice, ScanRun from app.db.models import Node, PendingDevice, ScanRun
from app.schemas.nodes import NodeCreate from app.schemas.nodes import NodeCreate
@@ -110,6 +111,7 @@ async def update_scan_config(payload: ScanConfig, _: str = Depends(get_current_u
try: try:
settings.scanner_ranges = payload.ranges settings.scanner_ranges = payload.ranges
settings.save_overrides() settings.save_overrides()
reschedule_status_checks(payload.interval_seconds)
return payload return payload
except Exception as exc: except Exception as exc:
raise HTTPException(status_code=500, detail=str(exc)) from exc raise HTTPException(status_code=500, detail=str(exc)) from exc
+6
View File
@@ -53,5 +53,11 @@ def start_scheduler() -> None:
logger.info("Scheduler started — status checks every %ds", settings.status_checker_interval) logger.info("Scheduler started — status checks every %ds", settings.status_checker_interval)
def reschedule_status_checks(interval_seconds: int) -> None:
"""Update the status check interval on the running scheduler."""
scheduler.reschedule_job("status_checks", trigger="interval", seconds=interval_seconds)
logger.info("Status checks rescheduled to every %ds", interval_seconds)
def stop_scheduler() -> None: def stop_scheduler() -> None:
scheduler.shutdown(wait=False) scheduler.shutdown(wait=False)
+20
View File
@@ -156,6 +156,26 @@ async def test_ignore_device(client: AsyncClient, headers, pending_device):
assert hidden_res.json() == [] assert hidden_res.json() == []
# --- Scan config ---
@pytest.mark.asyncio
async def test_update_scan_config_reschedules_interval(client: AsyncClient, headers):
"""Saving a new interval must reschedule the running APScheduler job immediately."""
with (
patch("app.api.routes.scan.settings") as mock_settings,
patch("app.api.routes.scan.reschedule_status_checks") as mock_reschedule,
):
mock_settings.scanner_ranges = []
mock_settings.save_overrides = lambda: None
res = await client.post(
"/api/v1/scan/config",
json={"ranges": ["192.168.1.0/24"], "interval_seconds": 30},
headers=headers,
)
assert res.status_code == 200
mock_reschedule.assert_called_once_with(30)
# --- Scan runs --- # --- Scan runs ---
@pytest.mark.asyncio @pytest.mark.asyncio