Package server
Overview
Package server runs an HTTP API with the timeouts, health checks and graceful shutdown that every service needs.
A Server has two listeners. The public one serves the API. The internal one, which mustn't be exposed outside the cluster, serves:
- /healthz, which is 200 while the process is running (liveness);
- /readyz, which is 200 until shutdown starts, then 503 (readiness);
- /debug/, with pprof and expvar.
Wire it in main, and run it until a signal:
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
err := server.New(api).WithLogger(logger).Server().Run(ctx)When ctx is cancelled, Run shuts down gracefully: it fails /readyz, waits the drain delay so load balancers stop sending requests, then lets in-flight requests finish within the shutdown timeout.
Index
- Constants
- Variables
func Drainingtype Builderfunc Newfunc (Builder) Serverfunc (Builder) WithAddrfunc (Builder) WithDrainDelayfunc (Builder) WithIdleTimeoutfunc (Builder) WithInternalAddrfunc (Builder) WithLoggerfunc (Builder) WithMaxHeaderBytesfunc (Builder) WithReadHeaderTimeoutfunc (Builder) WithReadTimeoutfunc (Builder) WithShutdownTimeoutfunc (Builder) WithWriteTimeout
type Server
Constants
const (
DefaultAddr = ":8080"
DefaultInternalAddr = ":9090"
DefaultReadHeaderTimeout = 5 * time.Second
DefaultReadTimeout = 30 * time.Second
DefaultWriteTimeout = 30 * time.Second
DefaultIdleTimeout = 120 * time.Second
DefaultMaxHeaderBytes = 64 << 10
DefaultDrainDelay = 5 * time.Second
DefaultShutdownTimeout = 20 * time.Second
)Defaults, used unless a With method changes them.
Variables
var ErrShutdownTimeout = errors.New("shutdown timed out")ErrShutdownTimeout is returned by Server.Run when requests are still in flight after the shutdown timeout. They're cancelled.
Functions
Draining source
func Draining(ctx context.Context) <-chan struct{}Draining returns a channel that's closed when the server that's handling the request starts shutting down. A handler that streams indefinitely should end its stream then, so the client reconnects to another instance; shutdown otherwise waits for it until the timeout. It returns nil, which never closes, outside a Server.
Types
Builder source
type Builder struct {
// contains filtered or unexported fields
}Builder configures a Server. Its With methods return a modified copy.
New source
func New(api http.Handler) BuilderNew returns a Builder for a server that serves api. It panics if api is nil.
(Builder) Server source
func (b Builder) Server() *ServerServer returns the configured server.
(Builder) WithAddr source
func (b Builder) WithAddr(addr string) BuilderWithAddr sets the public listener's address, such as ":8080".
(Builder) WithDrainDelay source
func (b Builder) WithDrainDelay(d time.Duration) BuilderWithDrainDelay sets how long Run waits, after failing /readyz, before it stops accepting connections. It should be longer than the load balancer's readiness check interval.
(Builder) WithIdleTimeout source
func (b Builder) WithIdleTimeout(d time.Duration) BuilderWithIdleTimeout sets how long an idle keep-alive connection is kept open.
(Builder) WithInternalAddr source
func (b Builder) WithInternalAddr(addr string) BuilderWithInternalAddr sets the internal listener's address, such as ":9090".
(Builder) WithLogger source
func (b Builder) WithLogger(logger *slog.Logger) BuilderWithLogger sets the logger for the server's own messages and for errors from net/http.
(Builder) WithMaxHeaderBytes source
func (b Builder) WithMaxHeaderBytes(n int) BuilderWithMaxHeaderBytes sets the largest request header net/http reads. Larger requests get a 431 (RFC 6585, Section 5).
(Builder) WithReadHeaderTimeout source
func (b Builder) WithReadHeaderTimeout(d time.Duration) BuilderWithReadHeaderTimeout sets how long a client may take to send the request headers.
(Builder) WithReadTimeout source
func (b Builder) WithReadTimeout(d time.Duration) BuilderWithReadTimeout sets how long a client may take to send the whole request.
(Builder) WithShutdownTimeout source
func (b Builder) WithShutdownTimeout(d time.Duration) BuilderWithShutdownTimeout sets how long Run waits for in-flight requests to finish before cancelling them.
(Builder) WithWriteTimeout source
func (b Builder) WithWriteTimeout(d time.Duration) BuilderWithWriteTimeout sets how long a handler may take to write its response, from the end of the request headers. A handler that streams extends its own deadline with http.ResponseController.
Server source
type Server struct {
// contains filtered or unexported fields
}Server is an API server with its internal listener. Build one with New.
(Server) Addr source
func (s *Server) Addr() net.AddrAddr returns the public listener's address, or nil before Listen.
(Server) InternalAddr source
func (s *Server) InternalAddr() net.AddrInternalAddr returns the internal listener's address, or nil before Listen.
(Server) Listen source
func (s *Server) Listen(ctx context.Context) errorListen binds both listeners, so that Server.Addr and Server.InternalAddr report the addresses actually bound, such as the port chosen for ":0". Run calls it if it hasn't been called.
(Server) Run source
func (s *Server) Run(ctx context.Context) errorRun serves until ctx is cancelled, then shuts down gracefully:
- /readyz starts failing with 503, and handlers' Draining channels close.
- Run waits the drain delay, while still serving requests.
- Both listeners stop accepting connections, and in-flight requests have the shutdown timeout to finish.
- Any still running have their contexts cancelled, and Run returns ErrShutdownTimeout.
It returns nil after a clean shutdown, or an error if a listener fails. A Server can be run only once.