GET /api/cdn: probe status endpoint (public, read-only)
Latest state + kbps + ~1h history (20 samples). curl it to check the CDN without digging through server.log.
This commit is contained in:
1 parent
eea538ab17
commit
a61e7dd0e7
1 file changed
+13
-1
+13
-1
@@ -25,6 +25,9 @@ from . import db, upstream, users
|
|||||||
ROOT = Path(__file__).parent.parent
|
ROOT = Path(__file__).parent.parent
|
||||||
app = FastAPI(title="ani-web")
|
app = FastAPI(title="ani-web")
|
||||||
|
|
||||||
|
# latest probe result + last 20 samples (~1h at 3-min spacing), for GET /api/cdn
|
||||||
|
_CDN = {"state": "unknown", "kbps": 0.0, "ts": 0.0, "hist": []}
|
||||||
|
|
||||||
|
|
||||||
def _cdn_probe():
|
def _cdn_probe():
|
||||||
"""Background probe: pull 64KB from the CDN every 3 min and log state
|
"""Background probe: pull 64KB from the CDN every 3 min and log state
|
||||||
@@ -56,18 +59,27 @@ def _cdn_probe():
|
|||||||
if now != state:
|
if now != state:
|
||||||
print(f"[probe] CDN {now} ({kbps:.0f} KB/s)", flush=True)
|
print(f"[probe] CDN {now} ({kbps:.0f} KB/s)", flush=True)
|
||||||
state = now
|
state = now
|
||||||
|
_CDN.update(state=now, kbps=round(kbps), ts=time.time())
|
||||||
|
_CDN["hist"].append({"t": time.time(), "kbps": round(kbps)})
|
||||||
|
del _CDN["hist"][:-20]
|
||||||
time.sleep(180)
|
time.sleep(180)
|
||||||
|
|
||||||
|
|
||||||
threading.Thread(target=_cdn_probe, daemon=True).start()
|
threading.Thread(target=_cdn_probe, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cdn")
|
||||||
|
async def cdn_status():
|
||||||
|
"""CDN health (read-only, public): latest probe + ~1h of history."""
|
||||||
|
return _CDN
|
||||||
|
|
||||||
# ---------- auth: multi-user, signed cookies ----------
|
# ---------- auth: multi-user, signed cookies ----------
|
||||||
users.migrate_legacy() # file-based legacy import; db.init() absorbs its output
|
users.migrate_legacy() # file-based legacy import; db.init() absorbs its output
|
||||||
db.init()
|
db.init()
|
||||||
_SIGNER = TimestampSigner(users.get_secret())
|
_SIGNER = TimestampSigner(users.get_secret())
|
||||||
_SESSION = "aniweb_session"
|
_SESSION = "aniweb_session"
|
||||||
_SESSION_AGE = 30 * 86400
|
_SESSION_AGE = 30 * 86400
|
||||||
_PUBLIC = {("/login", "GET"), ("/login", "POST")}
|
_PUBLIC = {("/login", "GET"), ("/login", "POST"), ("/api/cdn", "GET")}
|
||||||
_SECURE = os.environ.get("ANIWEB_SECURE") == "1" # set when served over HTTPS
|
_SECURE = os.environ.get("ANIWEB_SECURE") == "1" # set when served over HTTPS
|
||||||
|
|
||||||
# ponytail: in-memory lockout per username, single process — 5 fails -> 15 min
|
# ponytail: in-memory lockout per username, single process — 5 fails -> 15 min
|
||||||
|
|||||||
Reference in new issue
Block a user