from __future__ import annotations import asyncio import logging from app.db.session import SessionLocal from app.models import AoiOperation from app.services.aoi_operation_executor import AoiOperationExecutor logger = logging.getLogger("geointel.aoi_worker") class AoiOperationWorker: @staticmethod def run_once() -> int: db = SessionLocal() try: rows = db.query(AoiOperation).filter(AoiOperation.status.in_(("queued", "running"))).order_by(AoiOperation.created_at).limit(10).all() for operation in rows: try: AoiOperationExecutor.execute_next(db, operation.project_id, operation.id) except Exception: db.rollback() logger.exception("AOI partition execution failed operation_id=%s", operation.id) return len(rows) finally: db.close() @staticmethod async def run(stop_event: asyncio.Event, poll_seconds: float) -> None: while not stop_event.is_set(): processed = await asyncio.to_thread(AoiOperationWorker.run_once) if processed == 0: try: await asyncio.wait_for(stop_event.wait(), timeout=poll_seconds) except TimeoutError: pass