from __future__ import annotations import threading import time from datetime import date from backend.bootstrap.config import normalize_date class JobServiceMixin: def start_background_jobs(self) -> threading.Thread: return self.jobs.start_scheduler( self._background_refresh_tick, interval_seconds=5, initial_delay_seconds=3, ) def stop_background_jobs(self, timeout_seconds: float = 5) -> bool: scheduler_stopped = self.jobs.stop_scheduler(timeout_seconds) workers_stopped = self.jobs.wait_for_idle(timeout_seconds) return scheduler_stopped and workers_stopped def request_background_sync(self, trade_date: str) -> bool: normalized = normalize_date(trade_date) key = f"manual:{normalized}:{time.time_ns()}" return self.jobs.submit( "market.refresh", key, lambda: self.sync_dashboard(normalized), {"trade_date": normalized, "trigger": "administrator"}, ) def _background_refresh_tick(self) -> None: if not ( self.configured and self._system_credentials.get("background_refresh_enabled", True) ): return today = date.today().strftime("%Y%m%d") snapshot = self.database.get_snapshot(today) or {} if self._realtime_snapshot_due(today, snapshot): bucket = int(time.time() // 5) self.jobs.submit( "market.refresh", f"realtime:{today}:{bucket}", lambda: self.sync_dashboard(today), {"trade_date": today, "trigger": "realtime-poll"}, ) self._schedule_automatic_screeners(today, snapshot)