graceful

Signal-aware shutdown for servers, workers, and batch jobs. Independent of cli.

import "github.com/pressly/cli/graceful"

At a glance

Each name links to godoc.

FUNCTIONS
    func Run(fn func(context.Context) error, opts ...Option)
    func ListenAndServe(srv *http.Server, shutdownGrace time.Duration) func(context.Context) error

OPTIONS
    func WithRunTimeout(d time.Duration) Option
    func WithTerminationTimeout(d time.Duration) Option
    func WithImmediateTermination() Option
    func WithLogger(logger *slog.Logger) Option
    func WithStderr(w io.Writer) Option

Behavior

Exit codes:


Examples

HTTP server

server := &http.Server{
    Addr:    ":8080",
    Handler: mux,
}

graceful.Run(
    // Drain requests for up to 15 seconds.
    graceful.ListenAndServe(server, 15*time.Second),
    // Give the whole shutdown 30 seconds.
    graceful.WithTerminationTimeout(30*time.Second),
)

Batch job with a hard deadline

graceful.Run(
    func(ctx context.Context) error {
        // The function must return when ctx is canceled.
        return processBatch(ctx)
    },
    graceful.WithRunTimeout(1*time.Hour),
)

Immediate termination on first signal

graceful.Run(
    func(ctx context.Context) error {
        return runTask(ctx)
    },
    graceful.WithImmediateTermination(),
)

Silence shutdown messages

graceful.Run(fn,
    graceful.WithLogger(slog.New(slog.DiscardHandler)),
)