// ServeListenerForever is the same as ServeForever except it uses the specified // listener. This is useful in testing when an ephemeral port should be used. func ServeListenerForever(l net.Listener) error { // Wrap with logger handler := logginghandler.New(http.DefaultServeMux, log.GetVerbosity()) _, aps, err := net.SplitHostPort(l.Addr().String()) if err != nil { log.Errorf("govtil/net/server: failed to get port - %v", err) } log.Printf("govtil/net/server: starting on port %v", aps) // Serve err = http.Serve(l, handler) if err != nil { if vnet.SocketClosed(err) { err = nil // closed due to signal, no error } else { log.Errorf("govtil/net/server: %v", err) } } log.Println("govtil/net/server: Terminating") return err }
// Serve on a given port // // The server will log to the default logger and will gracefully terminate on // receipt of an interrupt or kill signal. // // The following URLs are defined: // / // /healthz // /varz // /streamz // /birpc // /debug/pprof // func ServeForever(port int) error { addr := ":" + fmt.Sprint(port) l, err := net.Listen("tcp", addr) if err != nil { log.Errorln("govtil/net/server: Failed to listen on", port, err) return err } // Close listen port on signals (causes http.Serve() to return) sigch := make(chan os.Signal) signal.Notify(sigch, []os.Signal{ syscall.SIGABRT, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGPWR, syscall.SIGQUIT, syscall.SIGSTOP, syscall.SIGTERM, }...) go func() { sig := <-sigch log.Println("govtil/net/server: Closing listen port", l.Addr().String(), "due to signal", sig) l.Close() }() logginghandler := logginghandler.New(http.DefaultServeMux, log.NORMAL) err = http.Serve(l, logginghandler) if err != nil { if vnet.SocketClosed(err) { err = nil // closed due to signal, no error } else { log.Errorln("govtil/net/server:", err) } } log.Println("govtil/net/server: Terminating") return err }