"""작업 단계 기록. 실행 순서는 도메인 서비스, 화면 문구는 프론트가 소유한다.""" from contextlib import asynccontextmanager from crud.job_crud import JobQueue class JobProgress: def __init__(self, job: dict, steps: tuple[str, ...]): self.job = job self.queue = JobQueue() self.state = { "attempt": job["attempts"], "steps": [{"id": step, "status": "pending"} for step in steps], } async def _set(self, step_id: str, status: str, reason: str | None = None): step = next(step for step in self.state["steps"] if step["id"] == step_id) step.update(status=status, reason=reason) if not await self.queue.set_progress(self.job, self.state): raise RuntimeError("작업 소유권이 만료되어 진행 기록을 중단합니다") @asynccontextmanager async def step(self, step_id: str): await self._set(step_id, "running") try: yield except BaseException: await self._set(step_id, "failed") raise else: await self._set(step_id, "done") async def skip(self, step_id: str, reason: str): await self._set(step_id, "skipped", reason)