"""JobManager — job lifecycle: create, track status, cancel.""" from __future__ import annotations import asyncio import uuid from dataclasses import dataclass, field from time import time from models.schemas import JobStatus @dataclass class Job: id: str message: str status: JobStatus = JobStatus.queued created_at: float = field(default_factory=time) task: asyncio.Task | None = field(default=None, repr=False) pipeline: bool = True rewritten_message: str = "" callback: str = "" # "synology" | "" callback_meta: dict = field(default_factory=dict) # username, user_id 등 class JobManager: def __init__(self) -> None: self._jobs: dict[str, Job] = {} def create(self, message: str) -> Job: job_id = uuid.uuid4().hex[:12] job = Job(id=job_id, message=message) self._jobs[job_id] = job return job def get(self, job_id: str) -> Job | None: return self._jobs.get(job_id) def set_status(self, job_id: str, status: JobStatus) -> None: job = self._jobs.get(job_id) if job: job.status = status def cancel(self, job_id: str) -> bool: job = self._jobs.get(job_id) if not job: return False if job.status in (JobStatus.completed, JobStatus.failed, JobStatus.cancelled): return False job.status = JobStatus.cancelled if job.task and not job.task.done(): job.task.cancel() return True def attach_task(self, job_id: str, task: asyncio.Task) -> None: job = self._jobs.get(job_id) if job: job.task = task job_manager = JobManager()