Add scheduled watchlist refresh support

This commit is contained in:
Dymas
2026-05-17 20:38:16 +02:00
parent 47480efa30
commit 6168acb272
8 changed files with 285 additions and 16 deletions
+75
View File
@@ -335,6 +335,81 @@ class WatchlistRefreshJobs:
self.current_job_id = None
class WatchlistAutoRefreshScheduler:
def __init__(self, config_getter, refresh_start_fn, start_worker=True):
self.config_getter = config_getter
self.refresh_start_fn = refresh_start_fn
self.lock = threading.RLock()
self.wakeup = threading.Event()
self.stop_event = threading.Event()
self.worker = None
self.last_enabled = None
self.last_interval_seconds = None
self.last_attempt_monotonic = None
if start_worker:
self.ensure_worker()
def ensure_worker(self):
with self.lock:
if self.worker is not None and self.worker.is_alive():
return
self.stop_event.clear()
self.worker = threading.Thread(target=self._run, daemon=True)
self.worker.start()
def shutdown(self, wait=False):
self.stop_event.set()
self.wakeup.set()
worker = self.worker
if wait and worker is not None and worker.is_alive():
worker.join(timeout=WORKER_SHUTDOWN_TIMEOUT_SECONDS)
return worker is None or not worker.is_alive()
def notify_config_changed(self):
self.wakeup.set()
def _config_state(self):
config = self.config_getter() or {}
enabled = bool(config.get("watchlist_auto_refresh_enabled"))
try:
minutes = int(str(config.get("watchlist_auto_refresh_minutes", 60)).strip() or "60")
except (TypeError, ValueError):
minutes = 60
minutes = max(1, min(7 * 24 * 60, minutes))
return enabled, minutes * 60
def tick(self, now_monotonic=None):
now = time.monotonic() if now_monotonic is None else float(now_monotonic)
enabled, interval_seconds = self._config_state()
with self.lock:
changed = enabled != self.last_enabled or interval_seconds != self.last_interval_seconds
if changed:
self.last_enabled = enabled
self.last_interval_seconds = interval_seconds
self.last_attempt_monotonic = now
if not enabled:
return None
if self.last_attempt_monotonic is None:
self.last_attempt_monotonic = now
return interval_seconds
remaining = interval_seconds - (now - self.last_attempt_monotonic)
if remaining > 0:
return remaining
self.last_attempt_monotonic = now
try:
result = self.refresh_start_fn()
debug_log("watchlist.auto_refresh.tick", result=result)
except Exception as exc:
debug_log("watchlist.auto_refresh.error", error=exc)
return interval_seconds
def _run(self):
while not self.stop_event.is_set():
wait_seconds = self.tick()
self.wakeup.wait(timeout=wait_seconds)
self.wakeup.clear()
class DownloadQueue:
def __init__(self, config_getter, watchlist_sync_fn=None, job_prepare_fn=None, start_worker=True):
self.config_getter = config_getter