Skip to content

@HealthCheck & Pod Lifecycle

AGBoss applications running in Kubernetes or multi-instance worker clusters expose liveness and readiness health probes via await app.checkLiveness() and await app.checkReadiness(), register custom dependency probes with @HealthCheck, and coordinate graceful SIGTERM / SIGINT lease handoff through the 4-stage container lifecycle (OnInit, OnStart, OnStop, OnDestroy).

Complete @HealthCheck, Liveness, and Readiness example

Section titled “Complete @HealthCheck, Liveness, and Readiness example”

Every @HealthCheck class implements HealthCheckHandler, has a name ending with -health-check ([name.kind-suffix]), and is registered in @Application({ healthChecks }) ([health.not-a-health-check], [health.duplicate-name]):

Option Type Required Description
name string Yes Unique kebab-case identifier ending with -health-check (e.g., "claims-api-health-check").
timeout Milliseconds Yes Maximum duration check() may take (seconds(2)); if exceeded or thrown, the component reports HealthStatus.Unhealthy.
deps readonly Token[] No Constructor dependencies injected by the application container and verified against the constructor signature.

How app.checkLiveness() and app.checkReadiness() work

Section titled “How app.checkLiveness() and app.checkReadiness() work”

Both app.checkLiveness() and app.checkReadiness() resolve to a HealthReport { status, components } and never reject. The top-level status is the worst status across all checked components (HealthStatus.Healthy, HealthStatus.Degraded, or HealthStatus.Unhealthy):

Probe Checked Components (HealthComponentKind) Behavior
app.checkLiveness() Application ("application"), RecoveryLoop ("recovery-loop") Performs zero external I/O. Reports Unhealthy once app.close() begins (stopping) or if the 30-second recovery sweep has not completed within 90 seconds.
app.checkReadiness() Liveness components + Store ("store"), ModelProvider ("model-provider"), StepSlots ("step-slots"), Project ("project") Calls ping() on every configured repository (seconds(2) timeout), checks every @ModelProvider circuit breaker (open breaker -> Degraded), checks @Application({ maxConcurrentSteps }) saturation (all slots busy -> Degraded), and runs every @HealthCheck under its own timeout.

Custom @HealthCheck classes return branded results built exclusively with HealthCheckResult.healthy(), HealthCheckResult.degraded({ reason }), or HealthCheckResult.unhealthy({ reason }) (a Degraded instance continues serving traffic while signaling reduced capacity).

Pod lifecycle and concurrency settings reference

Section titled “Pod lifecycle and concurrency settings reference”
Setting / Hook Where Configured Default Purpose
healthChecks @Application [] @HealthCheck classes executed by await app.checkReadiness() under their configured timeout.
maxConcurrentSteps @Application Unbounded Maximum concurrent agent, router, and action steps on this pod ([limits.max-concurrent-steps-invalid]). When all slots are busy, checkReadiness() reports HealthStatus.Degraded (step-slots).
shutdownTimeout @Application seconds(25) Grace period on app.close() / SIGTERM before interrupting active executions and releasing their 30s leases (< kubernetes terminationGracePeriodSeconds).
compensationTimeout @Application seconds(15) Clean-up deadline per automatic @Action({ compensateWith }) rollback step.
pauseRecordRetention @Application hours(24) How long resolved (Taken, Cancelled) pause records are retained in PausedExecutionRepository so duplicate webhook clicks receive NotPausedError.
OnInit / OnStart / OnStop / OnDestroy @Injectable() providers — Deterministic 4-stage startup and reverse-topological shutdown hooks.