graceful

package module
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2023 License: MIT Imports: 11 Imported by: 2

README

Graceful

License GoDev Reference Go Report Card

Package graceful runs processes, such as servers, with graceful shutdown.

Example

Dual HTTP Server
// Create API server.
apiSrv := &http.Server{
	// ...
}
apiLis, err := net.Listen("tcp", cfg.HTTPAddress)
if err != nil {
	log.Error(err, "API HTTP server failed to listen", "addr", cfg.HTTPAddress)
	return err
}
defer apiLis.Close()
log.Info("API HTTP server listening", "addr", apiLis.Addr())

// Create debug server.
goingAway := make(chan struct{})
debugMux := http.NewServeMux()
debugMux.HandleFunc("/health/live", func(w http.ResponseWriter, _ *http.Request) {
	writeStatus(w, http.StatusOK)
})
debugMux.HandleFunc("/health/ready", func(w http.ResponseWriter, _ *http.Request) {
	select {
	case <-goingAway:
		writeStatus(w, http.StatusServiceUnavailable)
	default:
		writeStatus(w, http.StatusOK)
	}
})
debugSrv := &http.Server{
	Handler: debugMux,
	// ...
}
debugLis, err := net.Listen("tcp", cfg.DebugAddress)
if err != nil {
	log.Error(err, "Debug HTTP server failed to listen", "addr", cfg.DebugAddress)
	return err
}
defer debugLis.Close()
log.Info("Debug HTTP server listening", "addr", debugLis.Addr())


err = graceful.Run(ctx,
	// An OrderedGroup is a composition of Processes. All processes in the group
	// are started concurrently but they're stopped serially. In this case, the
	// debug server keeps serving until after the API server shuts down.
	graceful.OrderedGroup{
		graceful.HTTPServerProcess(apiSrv, apiLis),
		graceful.HTTPServerProcess(debugSrv, debugLis),
	},
	// Logger is used to write info logs about shutdown signals and error logs
	// about failed processes.
	graceful.WithLogger(log),
	// NotifyFuncs are called as soon as the shutdown signal is received, before
	// the shutdown delay. It gives the server time to pre-emptively fail health
	// checks and notify clients that it will be going away.
	graceful.WithNotifyFunc(func() { close(goingAway) }),
	// Delay gives time for clients and load balancers to remove the server from
	// their backend pools after a shutdown signal is received and before the
	// server stops listening.
	graceful.WithDelay(cfg.ShutdownDelay),
	// Grace gives time for pending requests to finish before the server
	// forcibly exits.
	graceful.WithGrace(cfg.ShutdownGrace),
)
if err != nil {
	log.Error(err, "Serving with graceful shutdown failed")
	return err
}
return nil

Documentation

Overview

Package graceful runs processes, such as servers, with graceful shutdown.

Index

Constants

View Source
const (
	DefaultDelay = time.Duration(0)
	DefaultGrace = 10 * time.Second
)

Variables

View Source
var ErrUnexpectedEnd = errors.New("graceful: process ended unexpectedly")

ErrUnexpectedEnd means that a process ended unexpectedly without returning an error before Shutdown was called.

Functions

func Contexts

func Contexts(ctx context.Context, log logr.Logger, delay, grace time.Duration) (warn, soft, hard context.Context)

Contexts returns three contexts which respectively serve as warning, soft, and hard shutdown signals. They are cancelled after TERM or INT signals are received.

When a shutdown signal is received, the warning context is cancelled. This is useful to start failing health checks while other traffic is still served.

If delay is positive, the soft context will be cancelled after that duration. This is useful to allow loadbalancer updates before the server stops accepting new requests.

If grace is positive, the hard context will be cancelled that duration after the soft context is cancelled. This is useful to set a maximum time to allow pending requests to complete.

Repeated TERM or INT signals will bypass any delay or grace time.

func Run added in v0.5.0

func Run(ctx context.Context, process Process, options ...Option) error

Run executes the process with the given context and options.

Types

type ConcurrentGroup added in v0.5.0

type ConcurrentGroup []Process

A ConcurrentGroup is a composition of Processes. All processes in the group are started and stopped concurrently.

func (ConcurrentGroup) Run added in v0.5.0

func (procs ConcurrentGroup) Run(ctx context.Context) error

func (ConcurrentGroup) Shutdown added in v0.5.0

func (procs ConcurrentGroup) Shutdown(ctx context.Context) error

type GRPCServer added in v0.4.0

type GRPCServer interface {
	Serve(net.Listener) error
	GracefulStop()
	Stop()
}

A GRPCServer is an interface for a grpc.Server.

type Option added in v0.5.0

type Option interface {
	// contains filtered or unexported methods
}

An Option overrides a default behavior.

func WithDelay added in v0.5.0

func WithDelay(delay time.Duration) Option

WithDelay returns an Option that sets the shutdown delay period.

For a server, this gives time for clients and load balancers to remove it from their backend pools after a shutdown signal is received and before it stops listening.

func WithGrace added in v0.5.0

func WithGrace(grace time.Duration) Option

WithGrace returns an Option that sets the shutdown grace period.

For a server, this gives time for pending requests to complete before it forcibly exits.

func WithLogger added in v0.5.0

func WithLogger(log logr.Logger) Option

WithLogger returns an Option that sets a logger.

func WithNotifyFunc added in v0.5.0

func WithNotifyFunc(notify func()) Option

WithNotifyFunc returns an Option that adds the given notify function to a list of those that will be called when the shutdown process is initially triggered. It will be called before the shutdown delay.

For a server, this gives it time to pre-emptively fail health checks or notify clients that it will be going away.

type OrderedGroup added in v0.5.0

type OrderedGroup []Process

An OrderedGroup is a composition of Processes. All processes in the group are started concurrently but they're stopped serially.

func (OrderedGroup) Run added in v0.5.0

func (procs OrderedGroup) Run(ctx context.Context) error

func (OrderedGroup) Shutdown added in v0.5.0

func (procs OrderedGroup) Shutdown(ctx context.Context) error

type Process added in v0.5.0

type Process interface {
	// Run starts the process with the given context and waits until it's stopped.
	// It returns an error if the process cannot be started or fails unexpectedly.
	// It does not return an error if it's stopped by the Shutdown method.
	Run(context.Context) error

	// Shutdown stops the process with the given context.
	// It stops accepting new work and waits for any pending work to finish.
	// If the context is cancelled, it abandons any pending work and returns an error.
	Shutdown(context.Context) error
}

A Process is a unit of execution that runs indefinitely until it's signaled to stop.

func GRPCServerProcess added in v0.5.0

func GRPCServerProcess(lis net.Listener, srv GRPCServer) Process

GRPCServerProcess converts a net.Listener and grpc.Server into a graceful.Process.

func HTTPServerProcess added in v0.5.0

func HTTPServerProcess(lis net.Listener, srv *http.Server) Process

HTTPServerProcess converts a net.Listener and http.Server into a graceful.Process.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL