Conversation
Well-placed circuit breaker for the hot Points:
|
|
Withdrawing this PR as superseded for the reported #96591 incident by merged #108130. I verified the current upstream implementation returns the structured state_db_corrupt 503 response for both usage and model analytics, throttles warnings per store, and leaves the database untouched; its corrupt-store regression passes. My additional database-reopen backoff is not part of that upstream fix, but does not justify replacing the shared response contract or continuing a competing fix for the now-closed issue. I am preserving the branch history for reference. |
Summary
I prevent a damaged
state.dbfrom turning/api/analytics/usageinto an unbounded database-open and traceback loop. Usage reads now fail closed with a bounded, profile-scoped circuit instead of retrying SQLite on every request.Fixes #96591
Root cause
The usage endpoint sent
_get_usage_analytics()to a worker thread but allowed everysqlite3.DatabaseErrorto escape. A persistent corrupt-image error therefore reopened the same file on every request, generated a full server traceback each time, and offered callers no retry guidance.Changes
Retry-Afterwhile the circuit is openhermes doctorI intentionally did not rename, delete, recreate, or repair
state.dbfrom the live dashboard request path. Recovery remains with the existing explicit repair tooling.Tests
scripts/run_tests.sh tests/hermes_cli/test_web_server.py -q— 176 passedscripts/run_tests.sh tests/hermes_cli/test_web_server_usage_db_circuit.py -q— 1 passedThe regression uses an actual non-SQLite
state.dband verifies that two requests produce one database attempt, one concise log, a 503/Retry-After response, and no modification to the damaged bytes.