Files
RadioPropagationApi/api/app/services/jobs.py
T
2026-06-24 07:50:00 +03:00

101 lines
2.2 KiB
Python

from __future__ import annotations
import json
from typing import Any
from uuid import uuid4
import redis
from app.config import get_settings
from app.models.jobs import JobResponse, JobStatus
JOB_KEY_PREFIX = "radio:job:"
_memory_store: dict[str, dict[str, Any]] = {}
def _redis_client() -> redis.Redis | None:
try:
client = redis.from_url(get_settings().redis_url, decode_responses=True)
client.ping()
return client
except redis.RedisError:
return None
def _load_raw(job_id: str) -> dict[str, Any] | None:
client = _redis_client()
if client is not None:
raw = client.get(f"{JOB_KEY_PREFIX}{job_id}")
if raw is None:
return None
return json.loads(raw)
return _memory_store.get(job_id)
def _save_raw(job_id: str, data: dict[str, Any]) -> None:
client = _redis_client()
if client is not None:
client.setex(
f"{JOB_KEY_PREFIX}{job_id}",
get_settings().job_ttl_seconds,
json.dumps(data),
)
return
_memory_store[job_id] = data
def create_job(
kind: str,
payload: dict[str, Any],
*,
status: JobStatus = "queued",
result: dict[str, Any] | None = None,
) -> str:
job_id = str(uuid4())
_save_raw(
job_id,
{
"status": status,
"kind": kind,
"payload": payload,
"result": result,
"error": None,
},
)
return job_id
def get_job(job_id: str) -> JobResponse | None:
data = _load_raw(job_id)
if data is None:
return None
return JobResponse(
status=data["status"],
result=data.get("result"),
error=data.get("error"),
)
def get_job_record(job_id: str) -> dict[str, Any] | None:
return _load_raw(job_id)
def update_job(
job_id: str,
*,
status: JobStatus | None = None,
result: dict[str, Any] | None = None,
error: str | None = None,
) -> None:
data = _load_raw(job_id)
if data is None:
raise KeyError(f"Job not found: {job_id}")
if status is not None:
data["status"] = status
if result is not None:
data["result"] = result
if error is not None:
data["error"] = error
_save_raw(job_id, data)