Holds the k8s readiness-probe status and enforces a drain window on shutdown.
On SIGTERM, OTP walks the supervision tree in reverse start order and
terminates children in reverse order. This GenServer must be the last
child of your application supervisor so it terminates first. Its
terminate/2 flips the /probe/readiness probe to 503 via :persistent_term
and sleeps for the drain window, giving Kubernetes time to stop routing
traffic and allowing in-flight requests to finish before other resources
(Repo, Endpoint, etc.) are torn down.
Note that the Endpoint keeps running and serving requests for the full drain
window — only its readiness status changes. A caller with a persistent
(keep-alive) connection already open to this instance can therefore keep
reusing it, and keep seeing 503s, for the whole window, regardless of how
quickly Kubernetes removes the instance from the Service's endpoints.
KubernetesProbes.Plug closes the connection on a draining 503 specifically
to prevent that — see its docs.
Usage
# lib/my_app/application.ex — last entry in children
children = [
MyApp.Repo,
MyAppWeb.Endpoint,
{KubernetesProbes.Drainer, otp_app: :my_app}
]Configuration
# config/config.exs — production default
config :my_app, KubernetesProbes.Drainer, wait: 20_000
# config/dev.exs — avoid 20s hang on Ctrl-C
config :my_app, KubernetesProbes.Drainer, wait: 100
# config/test.exs — avoid slow suite teardown
config :my_app, KubernetesProbes.Drainer, wait: 10Options
:otp_app— the OTP application to read configuration from (required).:wait— drain window in milliseconds. Can be set via config (see above) or passed directly to override config:{KubernetesProbes.Drainer, otp_app: :my_app, wait: 5_000}. Defaults to20_000.
Summary
Functions
Returns a specification to start this module under a supervisor.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec status() :: :running | :stopping