@@ -67,31 +67,44 @@ func StartSignalToggle() {
6767 }()
6868}
6969
70- // StartHealthServer serves liveness (/healthz) and readiness (/readyz) on addr
71- // in a goroutine. Readiness reports 503 while any inbound or outbound plugin is
72- // still waiting on a dependency (e.g. a credential file that hasn't landed yet).
73- func StartHealthServer (inboundH , outboundH * pipeline.Holder , addr string ) {
70+ // StartHealthServer binds addr, serves liveness (/healthz) and readiness
71+ // (/readyz) in a goroutine, and returns the server for graceful shutdown.
72+ // Readiness reports 503 while any inbound or outbound plugin is still waiting on
73+ // a dependency (e.g. a credential file that hasn't landed yet). A bind failure
74+ // is returned so the caller can decide how to handle it; a serve-time failure
75+ // after bind is logged.
76+ func StartHealthServer (inboundH , outboundH * pipeline.Holder , addr string ) (* http.Server , error ) {
77+ mux := http .NewServeMux ()
78+ mux .HandleFunc ("/healthz" , func (w http.ResponseWriter , r * http.Request ) {
79+ w .WriteHeader (http .StatusOK )
80+ })
81+ mux .HandleFunc ("/readyz" , func (w http.ResponseWriter , r * http.Request ) {
82+ if name := inboundH .NotReadyPlugin (); name != "" {
83+ http .Error (w , "inbound plugin not ready: " + name , http .StatusServiceUnavailable )
84+ return
85+ }
86+ if name := outboundH .NotReadyPlugin (); name != "" {
87+ http .Error (w , "outbound plugin not ready: " + name , http .StatusServiceUnavailable )
88+ return
89+ }
90+ w .WriteHeader (http .StatusOK )
91+ })
92+ srv := & http.Server {
93+ Addr : addr ,
94+ Handler : mux ,
95+ ReadHeaderTimeout : 10 * time .Second ,
96+ }
97+ listener , err := net .Listen ("tcp" , addr )
98+ if err != nil {
99+ return nil , err
100+ }
74101 go func () {
75- mux := http .NewServeMux ()
76- mux .HandleFunc ("/healthz" , func (w http.ResponseWriter , r * http.Request ) {
77- w .WriteHeader (http .StatusOK )
78- })
79- mux .HandleFunc ("/readyz" , func (w http.ResponseWriter , r * http.Request ) {
80- if name := inboundH .NotReadyPlugin (); name != "" {
81- http .Error (w , "inbound plugin not ready: " + name , http .StatusServiceUnavailable )
82- return
83- }
84- if name := outboundH .NotReadyPlugin (); name != "" {
85- http .Error (w , "outbound plugin not ready: " + name , http .StatusServiceUnavailable )
86- return
87- }
88- w .WriteHeader (http .StatusOK )
89- })
90- slog .Info ("health server listening" , "addr" , addr )
91- if err := http .ListenAndServe (addr , mux ); err != nil {
92- slog .Warn ("health server failed" , "error" , err )
102+ slog .Info ("health server listening" , "addr" , listener .Addr ().String ())
103+ if err := srv .Serve (listener ); err != nil && err != http .ErrServerClosed {
104+ slog .Error ("health server failed" , "error" , err )
93105 }
94106 }()
107+ return srv , nil
95108}
96109
97110// StartStatServer binds addr for the stats/config-inspection server, serves it
0 commit comments