101 lines
2.2 KiB
Python
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)
|