"""Worker 入口:周期回填到期结算指数 + 自动备份。""" from __future__ import annotations import logging import signal import sys import time from typing import Any from apps.collector.okx_rest import OkxRestClient from apps.worker.settle import backfill_settlements from packages.config import get_settings, reload_settings from packages.db import Repository from packages.db.backup import run_auto_backup, should_auto_backup logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s [worker] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) log = logging.getLogger("worker") _STOP = False def _handle_signal(signum: int, _frame: Any) -> None: global _STOP log.info("signal %s received, stopping…", signum) _STOP = True def _maybe_auto_backup() -> None: s = reload_settings() if not should_auto_backup( s.backup_dir_path, enabled=s.backup_auto_enabled, interval_hours=s.backup_interval_hours, ): return try: dest = run_auto_backup( s.db_path, s.backup_dir_path, tz=s.tz, keep=s.backup_keep_count, ) log.info("auto backup ok: %s", dest.name) except Exception as e: # noqa: BLE001 log.exception("auto backup failed: %s", e) def run() -> int: settings = get_settings() interval = max(60, int(settings.settle_backfill_interval_sec)) log.info( "start settle backfill interval=%ss db=%s backup_auto=%s every=%sh", interval, settings.db_path, settings.backup_auto_enabled, settings.backup_interval_hours, ) repo = Repository(settings.db_path) client = OkxRestClient( base_url=settings.okx_base_url, proxy=settings.okx_proxy or None, ) try: # 启动时先尝试一次自动备份(若到期) _maybe_auto_backup() while not _STOP: try: result = backfill_settlements( repo, underlying=settings.underlying, index_inst_id=settings.index_inst_id, client=client, ) log.info( "backfill filled=%s skipped=%s errors=%s", len(result["filled"]), len(result["skipped"]), len(result["errors"]), ) for err in result["errors"][:5]: log.warning(" %s", err) except Exception as e: # noqa: BLE001 log.exception("backfill loop failed: %s", e) _maybe_auto_backup() end = time.monotonic() + interval while not _STOP and time.monotonic() < end: time.sleep(min(1.0, end - time.monotonic())) finally: client.close() repo.close() log.info("stopped") return 0 def main() -> None: signal.signal(signal.SIGINT, _handle_signal) signal.signal(signal.SIGTERM, _handle_signal) sys.exit(run()) if __name__ == "__main__": main()