lifecycle

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package lifecycle provides a documented, cooperative graceful-shutdown contract for GoFastr applications. It formalises the drain-in-flight / stop-accepting / flush-queues sequence and exposes plugin hooks so batteries can cooperate during shutdown.

The lifecycle phases are:

  1. Drain — stop accepting new requests, let in-flight requests finish. Signaled via context cancellation. HTTP server Shutdown handles this.

  2. Flush — batteries flush their queues, buffers, and pending writes. Each battery that implements Drainer participates.

  3. Stop — final cleanup: close connections, release resources. OnStop hooks fire in reverse registration order.

Usage (typically done by App.Start automatically):

lc := lifecycle.New(app)
lc.RegisterDrainer(queueBattery)
lc.RegisterDrainer(cacheBattery)
app.OnStop(lc.Shutdown)

Index

Constants

This section is empty.

Variables

View Source
var ErrShuttingDown = errors.New("lifecycle: shutdown already started")

ErrShuttingDown is returned by RegisterDrainer / RegisterHealthChecker when called after Shutdown has begun.

Functions

func WithTimeout

func WithTimeout(d time.Duration) func(*Lifecycle)

WithTimeout sets the maximum duration for the drain phase. Default is 30 seconds.

Types

type DrainFunc

type DrainFunc func(ctx context.Context) error

DrainFunc is a function adapter for Drainer.

func (DrainFunc) Drain

func (f DrainFunc) Drain(ctx context.Context) error

Drain calls the underlying function.

type Drainer

type Drainer interface {
	Drain(ctx context.Context) error
}

Drainer is implemented by batteries and plugins that need to flush pending work during graceful shutdown. Drain should block until all in-flight work is complete or the context is cancelled.

Example: a queue battery drains its worker goroutines; a cache battery writes dirty entries to disk.

type HealthChecker

type HealthChecker interface {
	IsHealthy() bool
}

HealthChecker is implemented by components that can report readiness. During shutdown, components report unhealthy so load balancers stop sending traffic before the drain begins.

type Lifecycle

type Lifecycle struct {
	// contains filtered or unexported fields
}

Lifecycle manages the graceful shutdown sequence.

func New

func New() *Lifecycle

New creates a new Lifecycle manager.

func (*Lifecycle) AppendDrainer

func (lc *Lifecycle) AppendDrainer(d Drainer) error

AppendDrainer adds a drainer to the END of the drain order. Equivalent to RegisterDrainer; named explicitly when callers want to be explicit about ordering relative to PrependDrainer.

func (*Lifecycle) IsHealthy

func (lc *Lifecycle) IsHealthy() bool

IsHealthy returns true if all registered health checkers report healthy AND Shutdown has not been called. Returns true if no checkers are registered and the lifecycle is not shutting down.

func (*Lifecycle) PrependDrainer

func (lc *Lifecycle) PrependDrainer(d Drainer) error

PrependDrainer adds a drainer to the FRONT of the drain order — so it runs BEFORE every previously-registered drainer. Used to encode LIFO semantics for app-level stop hooks (last registered = first drained).

func (*Lifecycle) RegisterDrainer

func (lc *Lifecycle) RegisterDrainer(d Drainer) error

RegisterDrainer adds a component to the drain phase. Drainers are called sequentially during shutdown, in registration order. Returns ErrShuttingDown if Shutdown has already started — late registrations are dropped to keep the shutdown snapshot deterministic.

func (*Lifecycle) RegisterHealthChecker

func (lc *Lifecycle) RegisterHealthChecker(hc HealthChecker) error

RegisterHealthChecker adds a component that reports health status. During shutdown, all checkers are marked unhealthy. Returns ErrShuttingDown if Shutdown has already started.

func (*Lifecycle) RunWithSignals

func (lc *Lifecycle) RunWithSignals(ctx context.Context) error

RunWithSignals blocks until SIGINT or SIGTERM is received, then runs Shutdown using ctx as the parent context. Returns Shutdown's error, or nil if ctx is cancelled before a signal arrives.

func (*Lifecycle) RunWithSignalsUsing

func (lc *Lifecycle) RunWithSignalsUsing(ctx context.Context, shutdown func(context.Context) error) error

RunWithSignalsUsing is like RunWithSignals but invokes the supplied shutdown function instead of lc.Shutdown directly. Used by App so SIGTERM walks the App.Shutdown path (HTTP server drain + battery stop + lifecycle.Shutdown), not just lifecycle.Shutdown alone.

func (*Lifecycle) SetShutdownTimeout

func (lc *Lifecycle) SetShutdownTimeout(d time.Duration)

SetShutdownTimeout configures the drain timeout.

func (*Lifecycle) Shutdown

func (lc *Lifecycle) Shutdown(ctx context.Context) error

Shutdown executes the graceful shutdown sequence:

  1. Mark all health checkers as unhealthy (load balancers divert traffic).
  2. Drain all registered drainers concurrently with a timeout.
  3. Return the first error (if any).

The context is used as the parent for the drain timeout.

Jump to

Keyboard shortcuts

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