March Docs

Bastion.Health

lib/health.march — Bastion.Health: built-in health check endpoint.

Serves GET /health → 200 {"status":"ok"} in normal operation. During a drain (SIGTERM received), returns 503 {"status":"draining"}.

The drain state is stored in a Vault table so it can be toggled without restarting the process. Call Bastion.Health.start_drain() from a signal handler to transition to the draining state.

── Usage ──────────────────────────────────────────────────────────────────────

-- In your endpoint pipeline (before the router):
let c = Bastion.Health.plug(conn)

-- Register custom checks:
let checks = [
  Bastion.Health.check("depot", fn () ->
    match Pool.with_conn(my_pool, fn c -> Connection.simple_query(c, "SELECT 1") end) do
    Ok(_) -> Ok(())
    Err(e) -> Err(e)
    end
  end),
  Bastion.Health.check("vault", fn () ->
    if Vault.has(my_table, "heartbeat") do Ok(()) else Err("missing heartbeat key") end
  end)
]
let c = Bastion.Health.plug_with_checks(conn, checks)

Types

typeCheckCheck = Check(String, () -> Result((), String))#

Functions

fncheckcheck(name : String, probe : () -> Result((), String)) : Check#

Build a named health check from a probe function.

    Bastion.Health.check("depot", fn () ->
      match Pool.with_conn(my_pool, fn c -> Connection.simple_query(c, "SELECT 1") end) do
      Ok(_) -> Ok(())
      Err(e) -> Err(e)
      end
    end)
fndrainingdraining() : Bool#

Returns true when a drain is in progress (start_drain was called).

fnplugplug(conn)#

Plug that serves GET /health.

Returns 200 {"status":"ok"} normally, or 503 {"status":"draining"} when
start_drain() has been called.  Passes all other paths through.
fnplug_with_checksplug_with_checks(conn, checks : List(Check))#

Plug that serves GET /health with custom probe functions.

Each check's probe is called.  If all pass and the server is not draining,
returns 200.  If any check fails, returns 503 {"status":"unhealthy"}.  If
draining, returns 503 {"status":"draining"} (checks are skipped).
fnstart_drainstart_drain()#

Signal that a drain is beginning. The health endpoint will return 503 {"status":"draining"} until the process exits.

Call this in a SIGTERM handler to give load balancers time to stop routing
before the drain timeout fires.