Table of Contents

Class LiveSessionHealthCheck

Namespace
DatabentoDotNet.Extensions.Hosting
Assembly
DatabentoDotNet.Extensions.Hosting.dll

Reports one live session's State as a health status.

public sealed class LiveSessionHealthCheck : IHealthCheck
Inheritance
LiveSessionHealthCheck
Implements
Inherited Members

Remarks

Opt-in, and registered nowhere by default. AddDatabentoLive does not install this; AddHealthCheck(string?, HealthStatus?, IEnumerable<string>?) does, and a consumer who never calls it has no registration, runs no check, and pays for nothing. That is the whole reason the method is on the builder rather than inside the registration call.

The mapping is a decision, so here it is stated rather than left to be read off a switch:

StateResult
RunningHealthy — started, and reading.
NotStarted, StartingDegraded — coming up, not yet serving.
Reconnecting Degraded rather than unhealthy, and that is the judgement worth spelling out. The backoff is running and bounded, and most drops it exists for recover on the first attempt — so a reconnecting session is one that may well be serving again before the next probe. Reporting it unhealthy would take a pod out of rotation for a blip and, in a fleet, would do so to every pod at once. When the policy is exhausted the session faults, and that is unhealthy.
Stopped Unhealthy, which reads backwards until you ask what reaches this. A deliberate shutdown never does: the endpoint answering the probe stops with the host, so nobody is asking. What does reach it is a session whose stream ended while the host stayed up — the worker is alive and doing nothing, which is precisely the failure a health probe exists to surface. Reporting it healthy because "it was not an error" would hide a silently dead feed, the failure class this codebase exists to make loud.
Faulted Unhealthy, carrying Fault's message as the description and the exception itself on the result.

The two failing states report FailureStatus rather than Unhealthy literally. The framework applies that property only when a check throws, so a check that returns a status of its own has to honour it deliberately or the failureStatus argument on AddHealthCheck(string?, HealthStatus?, IEnumerable<string>?) would be decorative. It defaults to Unhealthy, which is what the table above describes.

Constructors

LiveSessionHealthCheck(LiveSessionRunner)

Creates a check over one session's runner.

public LiveSessionHealthCheck(LiveSessionRunner runner)

Parameters

runner LiveSessionRunner

The runner to report on.

Methods

CheckHealthAsync(HealthCheckContext, CancellationToken)

Reads State and maps it. Never blocks.

public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken)

Parameters

context HealthCheckContext

The framework's context. Its Registration supplies the failure status a caller configured.

cancellationToken CancellationToken

Unused: this check reads two fields and returns.

Returns

Task<HealthCheckResult>

The session's status, described.

Remarks

Synchronous work behind a Task<TResult>, because the interface is asynchronous and this is not. Nothing here touches the socket — a health check that probed the gateway would bill for a probe and could block the endpoint behind a network timeout; the runner already knows the answer, having been told by the loop.

The interpolated descriptions allocate, and that is fine here and only here: this runs once per probe, not once per record.