Class: Pgbus::Web::HealthApp
- Inherits:
-
Object
- Object
- Pgbus::Web::HealthApp
- Defined in:
- lib/pgbus/web/health_app.rb
Overview
Plain Rack app exposing HTTP liveness and readiness probes for orchestrators (Kubernetes kubelet, load balancers). Mount it in the host Rails app — no auth, no DB access on the liveness path:
# config/routes.rb
mount Pgbus::Web::HealthApp.new => "/pgbus/health"
# kubelet
livenessProbe: { httpGet: { path: /pgbus/health/livez, port: 3000 } }
readinessProbe: { httpGet: { path: /pgbus/health/readyz, port: 3000 } }
The supervisor process can also serve these two paths standalone via
HealthServer when config.health_port is set — that path
synthesizes a minimal Rack env and calls this same #call, so the routing
and verdict logic live in exactly one place.
Routing (env-only, no Rack::Request so it works under the bare-socket HealthServer too):
GET /livez → 200 text/plain "ok", unconditionally, NO database access
(the serving process is up — that is all liveness means).
GET /readyz → build a DataSource, run MCP::HealthAnalyzer#verdict:
OK / DEGRADED → 200, STALLED → 503, body = verdict JSON.
Any StandardError (DB unreachable) → 503 {"status":"ERROR"},
logged via Pgbus.logger (never swallowed).
unknown path → 404; non-GET on a known path → 405.
Constant Summary collapse
- LIVEZ =
"/livez"- READYZ =
"/readyz"
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(data_source: nil) ⇒ HealthApp
constructor
A new instance of HealthApp.
Constructor Details
#initialize(data_source: nil) ⇒ HealthApp
Returns a new instance of HealthApp.
52 53 54 |
# File 'lib/pgbus/web/health_app.rb', line 52 def initialize(data_source: nil) @data_source = data_source end |
Instance Method Details
#call(env) ⇒ Object
56 57 58 59 60 61 62 |
# File 'lib/pgbus/web/health_app.rb', line 56 def call(env) path = env["PATH_INFO"].to_s return not_found unless KNOWN_PATHS.include?(path) return method_not_allowed unless env["REQUEST_METHOD"] == "GET" path == LIVEZ ? livez : readyz end |