Skip to content

api: the health check answers 503 when the data directory is not writable - #401

Open
kurktchiev wants to merge 1 commit into
DuarteSantos8:mainfrom
kurktchiev:gh/health-writable
Open

kurktchiev wants to merge 1 commit into
DuarteSantos8:mainfrom
kurktchiev:gh/health-writable

Conversation

@kurktchiev

Copy link
Copy Markdown
Contributor

GET /api/health answered {"ok":true} for anything that had a live event
loop. The two failures that take an instance down don't touch the event
loop at all: ./data fills up, or its bind mount comes back read-only
after a host reboot. Then every sync, every sign-in, every audit line fails,
and the check goes on saying the service is fine.

So the check writes one empty file under DATA_DIR and removes it again, in
the same directory every real write goes to. It answers 503 when that throws,
which is what the compose healthcheck already reads as unhealthy (wget --spider looks at the status and nothing else). The 200 keeps its shape and
gains writable: true, so a human reading the JSON sees what was asserted
rather than guessing.

The probe is cached for five seconds. This route is unauthenticated, and a
create-and-unlink on every request is a disk write anyone who can reach the
port may ask for as fast as they like, so a poll can be up to five seconds
stale in exchange. Nothing is latched, so the poll right after the window
sees the mount that came back.

api 2 new tests (server-health-writable.test.js), run with node --test:
one for the writable case, one that makes the directory read-only mid-run
and checks the 503, the caching, the log line and the recovery after the
window. website/api.html regenerated from the updated spec.

Conflicts with #312 (generic prescription engine v2) in one place in
api/server.js, where both add new functions at the same spot. Keeping both
blocks resolves it.

🤖 Generated with Claude Code

GET /api/health answered {"ok":true} for anything that had a live event
loop. The two failures that actually take an instance down do not touch
the event loop at all: ./data fills up, or its bind mount comes back
read-only after a host reboot. Then every sync, every sign-in, every
audit line fails, and the check goes on saying the service is fine.

So the check writes: one empty file under DATA_DIR, removed again, on
the same directory every real write goes to. It answers 503 when that
throws, which is what the compose healthcheck already reads as
unhealthy (wget --spider looks at the status and nothing else). The 200
keeps its shape and gains writable: true, so a human reading the JSON
sees what was asserted rather than guessing.

The probe is cached for five seconds: this route is unauthenticated,
and a create-and-unlink on every request is a disk write anyone who can
reach the port may ask for as fast as they like, so a poll can be up to
five seconds stale in exchange. Nothing is latched — the poll after the
window sees the mount that came back.

api 2 new tests. website/api.html regenerated from the spec.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant