Class ReadinessState
HealthAggregator to gate the readiness probe.
This is the building block for zero-downtime shutdown. When a microservice begins shutting down it flips
the readiness state out of service before the listening connector stops.
The HealthAggregator consults this state for the READY probe so
/readyz returns 503 (out of service) as soon as shutdown begins — this lets a load
balancer / Kubernetes stop routing new traffic to the pod while in-flight requests drain. The
LIVE probe (/livez) is intentionally not gated, so Kubernetes does
not kill the pod mid-drain.
Resolution:
HealthAggregator and the embedded-server shutdown hooks resolve the state via
resolve(BeanStore): a ReadinessState bean registered in the relevant BeanStore wins;
otherwise the process-wide shared instance is used. In the standalone Jetty/Tomcat
microservice runtime, the embedded-server lifecycle component (e.g. JettyServerComponent) constructs
one per-service instance on start() — reusing an app/test-supplied @Bean ReadinessState
if one is already registered — and explicitly publishes that same instance into both the
microservice's bean store and the auto-mounted health-probe servlet's own bean store. The two sides then
observe each other's flips without ever touching shared(), so stopping one default-configured
microservice does not affect any other microservice's readiness in the same JVM. shared() remains
the last-resort fallback for embeddings that skip that dual-store publish (a plain servlet container, Spring
Boot without this integration, or unit tests that never register a bean).
This class is thread-safe; the flag is volatile.
See Also:
- Since:
- 10.0.0
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanisReady()Returns whether this service is currently ready to receive traffic.Marks this service as out of service so the readiness probe (/readyz) returns503.Marks this service as ready to receive traffic.onOutOfService(Object key, Runnable callback) Registers a callback to run when this state ismarked out of service.static ReadinessStateResolves the readiness state from the given bean store, falling back to thesharedinstance.static ReadinessStateshared()Returns the process-wide shared readiness state.
-
Constructor Details
-
ReadinessState
public ReadinessState()Constructor.The new state starts
ready.
-
-
Method Details
-
resolve
Resolves the readiness state from the given bean store, falling back to thesharedinstance.- Parameters:
beanStore- The bean store to consult. Can benull (resolves to the shared instance).- Returns:
- The resolved readiness state. Never
null .
-
isReady
Returns whether this service is currently ready to receive traffic.- Returns:
true if ready,false if out of service.
-
markReady
Marks this service as ready to receive traffic.Called when an embedded server starts so a freshly-(re)started service is ready.
- Returns:
- This object.
-
markOutOfService
Marks this service as out of service so the readiness probe (/readyz) returns503.Called at the very beginning of shutdown, before the listening connector stops.
- Returns:
- This object.
-
onOutOfService
Registers a callback to run when this state ismarked out of service.Lets components that hold long-lived connections (for example MCP
subscriptions/listenSSE streams) end them as soon as shutdown begins, instead of making the server's graceful drain wait out its full stop timeout for streams that would otherwise never finish on their own.Registering a second callback under the same
key replaces the first, so a component that is re-published on every server (re)start does not accumulate duplicate callbacks. Callbacks run on the thread that callsmarkOutOfService(); exceptions they throw are swallowed.Example:
state .onOutOfService("my-streams" , () ->streamRegistry .closeAll());- Parameters:
key- The owner of the callback (typically the registering component). Must not benull .callback- The callback to run. Must not benull .- Returns:
- This object.