BastionHotDeploy
BastionHotDeploy: connection-draining state machine for zero-downtime deploys.
Implements a simple four-state machine:
Starting → Serving ←→ Draining → StoppedState is persisted in a Vault table so it survives within the same process and is inspectable from tests without HTTP round-trips.
Storage layout ("hot_deploy_state" Vault table): "status" → String "serving" | "draining" | "starting" | "stopped" "in_flight" → Int number of requests currently being handled "drain_started_at" → Int monotonic timestamp (0 = not draining)
Typical usage:
BastionHotDeploy.start_drain()
-- wait for in-flight requests to finish …
let (code, body) = BastionHotDeploy.health_status(BastionHotDeploy.default_config())Types
Functions
Decrement the in-flight request counter by 1 (floored at 0). Call when a request finishes.
BastionHotDeploy.decrement_in_flight()Return the default DrainConfig.
BastionHotDeploy.default_config()
-- DrainConfig(30000, 5000, 503, true)Return (status_code, json_body) to send when rejecting a request during drain. Uses the configured drain_status_code (default 503).
let (code, body) = BastionHotDeploy.drain_response(config)Return the current DrainStatus. Defaults to Serving if no state has been set.
BastionHotDeploy.get_status()Return (status_code, json_body) appropriate for a health-check endpoint.
Serving → (200, "{\"status\":\"ok\"}")
Draining → (503, "{\"status\":\"draining\"}")
Starting → (503, "{\"status\":\"starting\"}")
Stopped → (503, "{\"status\":\"stopped\"}")
let (code, body) = BastionHotDeploy.health_status(BastionHotDeploy.default_config())Return the current in-flight request count.
BastionHotDeploy.in_flight_count()Increment the in-flight request counter by 1. Call at the start of each request.
BastionHotDeploy.increment_in_flight()Return true when the current status is Draining.
BastionHotDeploy.is_draining()Transition to Serving. Clears the drain_started_at timestamp.
Transition to Starting.
Return true when the deploy manager should refuse new connections (i.e. status is Draining or Stopped).
BastionHotDeploy.should_drain_request(config)Transition to Draining (from Serving). Records the drain start timestamp as 0 (no real monotonic clock in stdlib). Safe to call from any state.
BastionHotDeploy.start_drain()Transition to Stopped.