Repository navigation
feat: run user-supplied health probes on every health check route - #297
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #294.
The Litestar, FastAPI and FastMCP health check routes always answered
health_status: true, and the FastStream route could only ping its brokers. A service whose database or cache was down still reported healthy.HealthChecksConfiggainshealth_checks_probes: Mapping[str, HealthProbe], whereHealthProbeisCallable[[], Awaitable[bool]]. It is empty by default. On every request the health check route on Litestar, FastAPI, FastMCP and FastStream runs all probes concurrently. On FastStream they run alongside the broker pings from #296, and everything must pass.Falseor raises. A raised exception stays inside the route and is logged as one warning with the probe's name and the traceback, without the callable's repr. AFalseresult logs one warning with the name.health_status: false, on all four frameworks. The body does not name failing probes.functools.partial(broker.ping, timeout=5), and warn that a probe on an external dependency makes a liveness route restart pods during that dependency's outage.Following ADR 0002, the shared logic sits in
HealthChecksInstrument.define_health_status(). Framework subclasses only bind the route and pick the status code. FastStream overrides_define_framework_health_status()with its broker pings, so pings and probes run in a singleasyncio.gather.render_health_check_data()takes an optional keyword-onlyhealth_status, so existing callers are unaffected.Behavior change: FastStream's unhealthy response is now the JSON body with
health_status: falseinstead of the plain-textService is unhealthy. The status code stays 500.With no probes registered, the Litestar, FastAPI and FastMCP routes respond exactly as before, and their existing tests pass unchanged.
CONTEXT.mdadds the term Health probe, carried over from the maintainer's draft.Tests, written first: a parametrized test on each of the four frameworks (all pass, one returns
False, one raises) that checks the status, the body and which probes were logged. A FastStream test checks that a passing probe with a failing broker ping gives 500. A base instrument test checks that two probes sleeping 0.2 s each finish in under 0.3 s.Out of scope: #295, an enforced timeout,
FreeBootstrapper, and separate liveness and readiness routes.