from __future__ import annotations
import asyncio
from contextlib import asynccontextmanager
from dataclasses import dataclass
from typing import AsyncIterator, Protocol
@dataclass
class Job:
id: str
payload: dict[str, str]
class JobStore(Protocol):
async def reserve(self) -> Job | None: ...
async def complete(self, job_id: str) -> None: ...
@asynccontextmanager
async def worker_span(job: Job) -> AsyncIterator[None]:
print("start", job.id)
try:
yield
finally:
print("end", job.id)
class Worker:
def __init__(self, store: JobStore) -> None:
self._store = store
async def run_once(self) -> bool:
job = await self._store.reserve()
if job is None:
return False
async with worker_span(job):
await asyncio.sleep(0)
await self._store.complete(job.id)
return True