Class: Pgbus::Web::HealthServer
- Inherits:
-
Object
- Object
- Pgbus::Web::HealthServer
- Defined in:
- lib/pgbus/web/health_server.rb
Overview
Standalone HTTP health server for the supervisor process. When
config.health_port is set, Supervisor#run starts one of these so a
Kubernetes kubelet can probe the supervisor directly — the process that
forks and watches workers — without the supervisor having to boot Rails,
Puma, or the dashboard.
It is intentionally tiny: one accept-loop thread over a TCPServer that
reads only the HTTP request line (GET /readyz HTTP/1.1), synthesizes a
minimal Rack env, and hands it to Pgbus::Web::HealthApp#call. All routing and the
OK/DEGRADED/STALLED → status mapping live in HealthApp, so the mounted-in-
Rails path and this standalone path share exactly one implementation.
This is a health probe surface, not a general HTTP server: it speaks just enough HTTP/1.0 to answer a kubelet. It only parses the request line (method + path), ignores headers and body, and closes the connection after each response (no keep-alive).
Instance Attribute Summary collapse
-
#port ⇒ Integer?
readonly
The bound port.
Instance Method Summary collapse
-
#initialize(port:, bind: "127.0.0.1", app: nil, logger: nil) ⇒ HealthServer
constructor
A new instance of HealthServer.
-
#start ⇒ Object
Bind the port and start the accept loop.
-
#stop ⇒ Object
Close the listening socket (unblocking the accept loop, which then exits) and join the thread.
Constructor Details
#initialize(port:, bind: "127.0.0.1", app: nil, logger: nil) ⇒ HealthServer
Returns a new instance of HealthServer.
39 40 41 42 43 44 45 46 47 |
# File 'lib/pgbus/web/health_server.rb', line 39 def initialize(port:, bind: "127.0.0.1", app: nil, logger: nil) @configured_port = port @bind = bind @app = app || HealthApp.new @logger = logger @server = nil @thread = nil @port = nil end |
Instance Attribute Details
#port ⇒ Integer? (readonly)
Returns the bound port. Equals the configured port, or the OS-assigned port when the configured port was 0 (used in tests). nil before #start.
37 38 39 |
# File 'lib/pgbus/web/health_server.rb', line 37 def port @port end |
Instance Method Details
#start ⇒ Object
Bind the port and start the accept loop. Idempotent: a second call while running is a no-op (so a supervisor restart path can't double-bind).
51 52 53 54 55 56 57 58 |
# File 'lib/pgbus/web/health_server.rb', line 51 def start return if @server @server = TCPServer.new(@bind, @configured_port) @port = @server.addr[1] @thread = Thread.new { accept_loop } logger.info { "[Pgbus::Web::HealthServer] listening on #{@bind}:#{@port} (/livez, /readyz)" } end |
#stop ⇒ Object
Close the listening socket (unblocking the accept loop, which then exits) and join the thread. Safe to call when never started or twice.
62 63 64 65 66 67 68 69 |
# File 'lib/pgbus/web/health_server.rb', line 62 def stop server = @server @server = nil close_socket(server) @thread&.join(2) @thread = nil @port = nil end |