Upgrade configuration and Docker stack to v2.0.0

This commit is contained in:
2026-06-22 14:49:56 -04:00
parent 2f2a5e9b4a
commit 0d2ecbd218
19 changed files with 779 additions and 495 deletions
+49 -9
View File
@@ -14,6 +14,7 @@ router = APIRouter(prefix="/admin/api", tags=["Admin"])
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
ALLOWED_DOCS = {
"README.md": PROJECT_ROOT / "README.md",
"ROADMAP.md": PROJECT_ROOT / "docs" / "ROADMAP.md",
"USER_GUIDE.md": PROJECT_ROOT / "docs" / "USER_GUIDE.md",
"ARCHITECTURE.md": PROJECT_ROOT / "docs" / "ARCHITECTURE.md",
"API_GUIDE.md": PROJECT_ROOT / "docs" / "API_GUIDE.md",
@@ -82,21 +83,60 @@ async def get_queue_status(
request: Request,
_: APIClient = Depends(require_scope("admin"))
) -> Dict[str, Any]:
"""Get ARQ queue status using the redis connection."""
"""Get ARQ queue status including Dead Letter Queue."""
redis = request.app.state.redis
# Note: A real implementation would parse the ARQ keys here.
# For now, we return basic statistics by probing redis directly with arq known queues.
# Count pending jobs in arq:queue
from app.workers.dead_letter import get_dead_job_count
pending_count = await redis.llen("arq:queue") if hasattr(redis, "llen") else 0
# In ARQ, active jobs are harder to count without querying the worker sets,
# so we return pending count.
dead_count = await get_dead_job_count(redis)
return {
"pending_jobs": pending_count,
"status": "active"
"dead_jobs": dead_count,
"status": "active",
}
# ─────────────────────────────────────────────────────────────
# Dead Letter Queue
# ─────────────────────────────────────────────────────────────
@router.get("/queue/dead")
async def list_dead_jobs(
request: Request,
_: APIClient = Depends(require_scope("admin")),
limit: int = 50,
) -> list[dict]:
"""List dead jobs from the Dead Letter Queue."""
from app.workers.dead_letter import get_dead_jobs
redis = request.app.state.redis
return await get_dead_jobs(redis, limit=limit)
@router.post("/queue/dead/{index}/retry")
async def retry_dead_job(
request: Request,
index: int,
_: APIClient = Depends(require_scope("admin")),
) -> dict:
"""Retry a dead job by its index (0 = most recent)."""
from app.workers.dead_letter import retry_dead_job
redis = request.app.state.redis
arq_pool = request.app.state.arq_pool
return await retry_dead_job(redis, arq_pool, index)
@router.delete("/queue/dead")
async def clear_dead_jobs(
request: Request,
_: APIClient = Depends(require_scope("admin")),
) -> Dict[str, Any]:
"""Clear all dead jobs from the DLQ."""
from app.workers.dead_letter import clear_dead_jobs
redis = request.app.state.redis
count = await clear_dead_jobs(redis)
return {"cleared": count}
@router.post("/clients/{client_id}/toggle")
async def toggle_client(
client_id: str,