job-processor / services /job_store.py
Eng-Musa's picture
own processor
2d765ca
Raw
History Blame Contribute Delete
1.98 kB
"""
Simple in-memory job store for the async CV processing pipeline.
Since the Python service runs as a single process on Hugging Face Spaces,
an in-memory dict is sufficient. Jobs are keyed by job_id (string UUID).
Each entry shape:
{
"status": "PENDING" | "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED",
"queue_position": int | None, # position in queue (1 = next to process)
"result": <ProcessorResponse payload dict> | None,
"error": <str> | None,
}
"""
from __future__ import annotations
import threading
from typing import Optional
_lock = threading.Lock()
_store: dict[str, dict] = {}
_queue_counter = 0 # monotonic counter to assign queue positions
def create_job(job_id: str) -> None:
with _lock:
_store[job_id] = {
"status": "PENDING",
"queue_position": None,
"result": None,
"error": None,
}
def set_queued(job_id: str) -> None:
"""Mark job as waiting in the Python processing queue."""
global _queue_counter
with _lock:
_queue_counter += 1
if job_id in _store:
_store[job_id]["status"] = "QUEUED"
_store[job_id]["queue_position"] = _queue_counter
def set_processing(job_id: str) -> None:
with _lock:
if job_id in _store:
_store[job_id]["status"] = "PROCESSING"
_store[job_id]["queue_position"] = None # no longer in queue
def set_completed(job_id: str, result: dict) -> None:
with _lock:
_store[job_id] = {"status": "COMPLETED", "result": result, "error": None}
def set_failed(job_id: str, error: str) -> None:
with _lock:
if job_id in _store:
_store[job_id]["status"] = "FAILED"
_store[job_id]["error"] = error
else:
_store[job_id] = {"status": "FAILED", "result": None, "error": error}
def get_job(job_id: str) -> Optional[dict]:
with _lock:
return _store.get(job_id)