fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

webserver: shutdown via close if using RPC (#516)

Our RPC system does not support shutdown and hijacks the underlying http
connection. This means shutdown is ineffective and just waits 10s before
calling close. Lets just quit faster in that case.

Test Plan: Run zoekt-webserver with and without rpc. Run kill and
observe behaviour.

+36 -8
+36 -8
cmd/zoekt-webserver/main.go
··· 299 299 } 300 300 }() 301 301 302 - if err := shutdownOnSignal(srv); err != nil { 303 - log.Fatalf("http.Server.Shutdown: %v", err) 302 + if s.RPC { 303 + // Our RPC system does not support shutdown and hijacks the underlying 304 + // http connection. This means shutdown is ineffective and just waits 10s 305 + // before calling close. Lets just quit faster in that case. 306 + if err := closeOnSignal(srv); err != nil { 307 + log.Fatalf("http.Server.Close: %v", err) 308 + } 309 + } else { 310 + if err := shutdownOnSignal(srv); err != nil { 311 + log.Fatalf("http.Server.Shutdown: %v", err) 312 + } 304 313 } 305 314 } 306 315 ··· 322 331 mux.Handle("/indexserver/", http.StripPrefix("/indexserver/", http.HandlerFunc(proxy.ServeHTTP))) 323 332 } 324 333 325 - // shutdownOnSignal will listen for SIGINT or SIGTERM and call 326 - // srv.Shutdown. Note it doesn't call anything else for shutting down. Notably 327 - // our RPC framework doesn't allow us to drain connections, so it when 328 - // Shutdown is called all inflight RPC requests will be closed. 329 - func shutdownOnSignal(srv *http.Server) error { 330 - c := make(chan os.Signal, 3) 334 + // shutdownSignalChan returns a channel which is listening for shutdown 335 + // signals from the operating system. maxReads is an upper bound on how many 336 + // times you will read the channel (used as buffer for signal.Notify). 337 + func shutdownSignalChan(maxReads int) <-chan os.Signal { 338 + c := make(chan os.Signal, maxReads) 331 339 signal.Notify(c, os.Interrupt) // terminal C-c and goreman 332 340 signal.Notify(c, syscall.SIGTERM) // Kubernetes 341 + return c 342 + } 333 343 344 + // closeOnSignal will listen for SIGINT or SIGTERM and call srv.Close. This is 345 + // not a graceful shutdown, see shutdownOnSignal. 346 + func closeOnSignal(srv *http.Server) error { 347 + c := shutdownSignalChan(1) 348 + <-c 349 + 350 + return srv.Close() 351 + } 352 + 353 + // shutdownOnSignal will listen for SIGINT or SIGTERM and call srv.Shutdown. 354 + // Note it doesn't call anything else for shutting down. Notably our RPC 355 + // framework doesn't allow us to drain connections, so when Shutdown we will 356 + // wait 10s before closing. 357 + // 358 + // Note: the call site for shutdownOnSignal should use closeOnSignal instead 359 + // if rpc mode is enabled due to the above limitation. 360 + func shutdownOnSignal(srv *http.Server) error { 361 + c := shutdownSignalChan(2) 334 362 <-c 335 363 336 364 // If we receive another signal, immediate shutdown