feat: add health and readiness checks - #20
Open
lukekim wants to merge 1 commit into
Open
Conversation
Adds SpiceClient.IsSpiceHealthyAsync and SpiceClient.IsSpiceReadyAsync, wrapping the runtime's /health and /v1/ready endpoints. Both probes reuse the configured HTTP client, so endpoint, credentials, TLS/mTLS and user agent already set on the builder apply without the caller reassembling them. An unreachable or unhealthy runtime is reported as false rather than raised as an exception, since that is the state the caller is asking about; cancellation requested by the caller propagates so a probe can participate in a wider timeout. The readiness body is matched exactly rather than by substring, because the runtime answers "not ready" while components are still loading. gospice and spice.js already expose these checks; this brings the .NET SDK in line.
There was a problem hiding this comment.
Pull request overview
Adds first-class health and readiness probes to the .NET SDK (SpiceClient.IsSpiceHealthyAsync / IsSpiceReadyAsync) by wrapping the runtime’s /health and /v1/ready HTTP endpoints, plus unit tests and README guidance so callers can gate startup without re-creating HTTP configuration.
Changes:
- Added
IsSpiceHealthyAsyncandIsSpiceReadyAsynctoSpiceClientandISpiceHttpClientand implemented them inSpiceHttpClientvia a shared probe helper. - Added loopback HTTP stub-based unit tests covering healthy/ready/unreachable/cancellation/disposed behaviors and exact-body matching.
- Documented health/readiness usage patterns in
README.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| SpiceTest/HealthCheckTest.cs | Adds unit tests with an in-process HTTP stub for health/readiness probe behavior. |
| Spice/src/SpiceClient.cs | Exposes new public health/readiness APIs on the main client surface. |
| Spice/src/Http/SpiceHttpClient.cs | Implements probe calls, including exact response-body matching and transport-failure handling. |
| Spice/src/Http/ISpiceHttpClient.cs | Extends the HTTP client interface with the new probe methods. |
| README.md | Documents how to use the new probes, including polling readiness. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+166
to
+172
| var (status, body) = respond(path); | ||
| var payload = Encoding.UTF8.GetBytes(body); | ||
| context.Response.StatusCode = (int)status; | ||
| context.Response.ContentType = "text/plain"; | ||
| context.Response.ContentLength64 = payload.Length; | ||
| await context.Response.OutputStream.WriteAsync(payload.AsMemory()).ConfigureAwait(false); | ||
| context.Response.Close(); |
Comment on lines
+165
to
+166
| Both probes return `false` when the runtime is unreachable rather than throwing, so they can be | ||
| polled directly. Pass a `CancellationToken` to bound how long a probe waits: |
Comment on lines
+91
to
+92
| var unreachable = $"http://127.0.0.1:{StubRuntime.ReserveFreePort()}"; | ||
| using var client = new SpiceClientBuilder().WithHttpAddress(unreachable).Build(); |
This was referenced Jul 27, 2026
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.
What
Adds
SpiceClient.IsSpiceHealthyAsyncandSpiceClient.IsSpiceReadyAsync, wrapping the runtime's/healthand/v1/readyendpoints.Why
Readiness is a core part of the runtime's API surface — it is what tells an application the runtime
has finished loading its datasets and accelerations and can serve queries. gospice
(
IsSpiceHealthy/IsSpiceReady) and spice.js (isSpiceHealthy/isSpiceReady) both expose it;the .NET SDK did not, so .NET callers had to stand up their own
HttpClientand re-supply theendpoint, credentials and TLS settings they had already given
SpiceClientBuilder. That is also thecheck a containerised service needs before it starts issuing queries.
Behaviour notes, for review:
HttpClient, so address, API key, TLS/mTLS and useragent carry over.
falserather than throwing — that is the state thecaller is asking about, and it matches gospice and spice.js. Cancellation requested by the caller
is propagated, so a probe can take part in a wider timeout.
/v1/readyanswersnot readywhile components are still loading, which contains the success token. Covered by a test.
Part of aligning capabilities across the Spice SDKs.
Verification
dotnet build -c Release, clean acrossnetstandard2.0,net8.0,net9.0and
net10.0(0 warnings, 0 errors, withTreatWarningsAsErrors).dotnet test -c Release: 123 passed / 0 failed onnet8.0andnet10.0(up from 115; 8 new tests).
net9.0compiles but could not be executed locally — no .NET 9runtime on this machine — so CI is the first run of that leg.
tests need neither: they run against an in-process loopback stub endpoint.
Note on the red CI
The Spice.ai Cloud integration tests are failing on this branch, and they fail identically on
trunk. Baseline run dispatched ontrunkat the same commit this branch forks from(run 30173590110):
trunkSame 33 tests, same failure — the Flight handshake against Spice.ai Cloud throws in
SpiceFlightClient.AuthenticateAsync, which this PR does not touch. Net effect of this change is+8 passing tests and no new failures. The pre-existing cloud-auth failure looks like an environment
or credential problem and is worth a separate issue.