Files
xiaobai-review/backend/jobs/registry.py
T

55 lines
1.8 KiB
Python

from __future__ import annotations
import json
from dataclasses import dataclass
from pathlib import Path
from backend.bootstrap.config import APP_DIR
@dataclass(frozen=True)
class JobDefinition:
job_id: str
schedule: str
input_date_policy: str
dependencies: tuple[str, ...]
lock_key: str
timeout_seconds: int
max_attempts: int
output_version: str
class JobRegistry:
def __init__(self, definitions: tuple[JobDefinition, ...]) -> None:
self.definitions = definitions
self._by_id = {item.job_id: item for item in definitions}
if len(self._by_id) != len(definitions):
raise ValueError("Background job IDs must be unique")
@classmethod
def load(cls, path: Path | None = None) -> "JobRegistry":
config_path = path or APP_DIR / "config" / "jobs.config.json"
payload = json.loads(config_path.read_text(encoding="utf-8"))
definitions = tuple(
JobDefinition(
job_id=str(item["id"]),
schedule=str(item["schedule"]),
input_date_policy=str(item["input_date_policy"]),
dependencies=tuple(str(value) for value in item.get("dependencies") or []),
lock_key=str(item["lock_key"]),
timeout_seconds=max(1, int(item["timeout_seconds"])),
max_attempts=max(1, int(item["max_attempts"])),
output_version=str(item["output_version"]),
)
for item in payload.get("jobs") or []
)
if not definitions:
raise ValueError("Background job registry is empty")
return cls(definitions)
def get(self, job_id: str) -> JobDefinition:
try:
return self._by_id[job_id]
except KeyError as exc:
raise ValueError(f"Background job is not registered: {job_id}") from exc