add graceful server shutdown (#1185)

* add graceful server shutdown

Also refactors server to use `http.Server` instead of the global
http.ListenAndServe method. In the future it allows us to set
ratelimits and timeouts for http connections.
This commit is contained in:
Victor Vrantchan 2017-02-07 16:02:08 -05:00 committed by GitHub
parent 482ff32be6
commit 838c73ff0a
2 changed files with 19 additions and 15 deletions

View file

@ -2,7 +2,6 @@ package cli
import (
"encoding/json"
"fmt"
"net/http"
"os"
"os/signal"
@ -131,32 +130,37 @@ the way that the kolide server works.
"query_result_store": resultStore,
}
http.Handle("/healthz", prometheus.InstrumentHandler("healthz", healthz(healthCheckers)))
http.Handle("/version", prometheus.InstrumentHandler("version", version.Handler()))
http.Handle("/assets/", prometheus.InstrumentHandler("static_assets", service.ServeStaticAssets("/assets/")))
http.Handle("/metrics", prometheus.InstrumentHandler("metrics", promhttp.Handler()))
http.Handle("/api/", apiHandler)
http.Handle("/", frontendHandler)
r := http.NewServeMux()
r.Handle("/healthz", prometheus.InstrumentHandler("healthz", healthz(healthCheckers)))
r.Handle("/version", prometheus.InstrumentHandler("version", version.Handler()))
r.Handle("/assets/", prometheus.InstrumentHandler("static_assets", service.ServeStaticAssets("/assets/")))
r.Handle("/metrics", prometheus.InstrumentHandler("metrics", promhttp.Handler()))
r.Handle("/api/", apiHandler)
r.Handle("/", frontendHandler)
srv := &http.Server{
Addr: config.Server.Address,
Handler: r,
}
errs := make(chan error, 2)
go func() {
if !config.Server.TLS {
logger.Log("transport", "http", "address", config.Server.Address, "msg", "listening")
errs <- http.ListenAndServe(config.Server.Address, nil)
errs <- srv.ListenAndServe()
} else {
logger.Log("transport", "https", "address", config.Server.Address, "msg", "listening")
errs <- http.ListenAndServeTLS(
config.Server.Address,
errs <- srv.ListenAndServeTLS(
config.Server.Cert,
config.Server.Key,
nil,
)
}
}()
go func() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGINT)
errs <- fmt.Errorf("%s", <-c)
sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig //block on signal
ctx, _ = context.WithTimeout(context.Background(), 30*time.Second)
errs <- srv.Shutdown(ctx)
}()
logger.Log("terminated", <-errs)

View file

@ -5,7 +5,7 @@ Building The Code
To setup a working local development environment, you must install the following minimum toolset:
* [Go](https://golang.org/dl/) (1.7 or greater)
* [Go](https://golang.org/dl/) (1.8 or greater)
* [Node.js](https://nodejs.org/en/download/current/) (and npm)
* [GNU Make](https://www.gnu.org/software/make/)
* [Docker](https://www.docker.com/products/overview#/install_the_platform)