50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
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)
|