feat: Added favicon (SVG + 32px PNG), apple-touch-icon, OG social image…
- "frontend/public/favicon.svg" - "frontend/public/favicon-32.png" - "frontend/public/apple-touch-icon.png" - "frontend/public/og-image.png" - "frontend/index.html" GSD-Task: S03/T01
This commit is contained in:
parent
ab11a00765
commit
48e1bd163d
6 changed files with 90 additions and 43 deletions
|
|
@ -11,6 +11,8 @@ Admin:
|
|||
GET /admin/pipeline/worker-status Active/reserved tasks from Celery inspect
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
|
@ -1263,13 +1265,15 @@ async def reindex_all(
|
|||
|
||||
# ── Admin: Worker status ─────────────────────────────────────────────────────
|
||||
|
||||
@router.get("/admin/pipeline/worker-status")
|
||||
async def worker_status():
|
||||
"""Get current Celery worker status — active, reserved, and stats."""
|
||||
WORKER_STATUS_CACHE_KEY = "chrysopedia:worker_status"
|
||||
WORKER_STATUS_CACHE_TTL = 10 # seconds
|
||||
|
||||
|
||||
def _inspect_workers():
|
||||
"""Synchronous Celery inspect — runs in a thread to avoid blocking the event loop."""
|
||||
from worker import celery_app
|
||||
|
||||
try:
|
||||
inspector = celery_app.control.inspect()
|
||||
inspector = celery_app.control.inspect(timeout=0.5)
|
||||
active = inspector.active() or {}
|
||||
reserved = inspector.reserved() or {}
|
||||
stats = inspector.stats() or {}
|
||||
|
|
@ -1300,14 +1304,40 @@ async def worker_status():
|
|||
"pool_size": worker_stats.get("pool", {}).get("max-concurrency") if isinstance(worker_stats.get("pool"), dict) else None,
|
||||
})
|
||||
|
||||
return {
|
||||
"online": len(workers) > 0,
|
||||
"workers": workers,
|
||||
}
|
||||
return {"online": len(workers) > 0, "workers": workers}
|
||||
|
||||
|
||||
@router.get("/admin/pipeline/worker-status")
|
||||
async def worker_status():
|
||||
"""Get current Celery worker status — active, reserved, and stats.
|
||||
|
||||
Results are cached in Redis for 10 seconds to avoid repeated slow
|
||||
Celery inspect round-trips. The synchronous inspect calls run in a
|
||||
thread so they never block the async event loop.
|
||||
"""
|
||||
# Try Redis cache first
|
||||
try:
|
||||
redis = await get_redis()
|
||||
cached = await redis.get(WORKER_STATUS_CACHE_KEY)
|
||||
await redis.aclose()
|
||||
if cached:
|
||||
return json.loads(cached)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Cache miss — run synchronous inspect in a thread
|
||||
try:
|
||||
result = await asyncio.to_thread(_inspect_workers)
|
||||
except Exception as exc:
|
||||
logger.warning("Failed to inspect Celery workers: %s", exc)
|
||||
return {
|
||||
"online": False,
|
||||
"workers": [],
|
||||
"error": str(exc),
|
||||
}
|
||||
return {"online": False, "workers": [], "error": str(exc)}
|
||||
|
||||
# Write to Redis cache (best-effort)
|
||||
try:
|
||||
redis = await get_redis()
|
||||
await redis.set(WORKER_STATUS_CACHE_KEY, json.dumps(result), ex=WORKER_STATUS_CACHE_TTL)
|
||||
await redis.aclose()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -4,6 +4,18 @@
|
|||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#0a0a12" />
|
||||
<meta name="description" content="Music production technique encyclopedia" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
<meta property="og:title" content="Chrysopedia" />
|
||||
<meta property="og:description" content="Music production technique encyclopedia" />
|
||||
<meta property="og:image" content="/og-image.png" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Chrysopedia" />
|
||||
<meta name="twitter:description" content="Music production technique encyclopedia" />
|
||||
<meta name="twitter:image" content="/og-image.png" />
|
||||
<title>Chrysopedia</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
BIN
frontend/public/apple-touch-icon.png
Normal file
BIN
frontend/public/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
BIN
frontend/public/favicon-32.png
Normal file
BIN
frontend/public/favicon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 624 B |
5
frontend/public/favicon.svg
Normal file
5
frontend/public/favicon.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
|
||||
<rect width="32" height="32" rx="6" fill="#0a0a12"/>
|
||||
<path d="M22 10.5a6.5 6.5 0 0 0-6.5-6.5C11.36 4 8 7.36 8 11.5c0 4.14 3.36 7.5 7.5 7.5" stroke="#22d3ee" stroke-width="3" fill="none" stroke-linecap="round"/>
|
||||
<circle cx="22" cy="22" r="3" fill="#22d3ee" opacity="0.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 369 B |
BIN
frontend/public/og-image.png
Normal file
BIN
frontend/public/og-image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Loading…
Add table
Reference in a new issue