Documentation
¶
Overview ¶
Package supervisor runs an application's long-running components (HTTP servers, queue workers, pub/sub listeners, the scheduler and background tasks) as goroutines in one process, and shuts them down gracefully.
A Supervisor provides:
- Roles: each component declares roles such as "http" or "workers", and Supervisor.Run can start only some of them, so one binary can run everything on a small server or be split across machines.
- Restart policies: a failing component can be left stopped (RestartNever), restarted with exponential backoff (RestartOnFailure), or stop the whole application (StopOnFailure). Panics are recovered and treated as failures.
- Staged shutdown: on shutdown, stages are canceled in ascending order (StageIngress first, StageBackground last), each draining before the next is canceled, all within one timeout.
- Health: Supervisor.Ready and Supervisor.Status feed readiness probes and diagnostics.
Most applications use the supervisor through anetos.App (app.Go, app.Component and app.Run) rather than directly.
Concept guide: docs/site/concepts/runtime-supervisor.md.
Index ¶
- Variables
- type Backoff
- type Component
- type ComponentStatus
- type Options
- type PanicError
- type Readier
- type Restart
- type Spec
- type Stage
- type State
- type Supervisor
- func (s *Supervisor) Add(spec Spec) error
- func (s *Supervisor) Declare(roles ...string)
- func (s *Supervisor) Ready() bool
- func (s *Supervisor) Roles() []string
- func (s *Supervisor) Run(ctx context.Context, roles ...string) error
- func (s *Supervisor) ShutdownDeadline() time.Time
- func (s *Supervisor) ShutdownStarted() time.Time
- func (s *Supervisor) Status() []ComponentStatus
Constants ¶
This section is empty.
Variables ¶
var ( // ErrAlreadyRun is returned by [Supervisor.Run] on a second call. ErrAlreadyRun = errors.New("supervisor: Run called more than once") // ErrStopping is returned by [Supervisor.Add] once shutdown has begun. ErrStopping = errors.New("supervisor: shutting down") // ErrShutdownTimeout is wrapped by the error [Supervisor.Run] returns when // components are still running after the shutdown timeout. ErrShutdownTimeout = errors.New("supervisor: shutdown timed out") )
Functions ¶
This section is empty.
Types ¶
type Backoff ¶
type Backoff struct {
// Initial is the delay before the first restart. Default 1s.
Initial time.Duration
// Max caps the delay. Default 30s. A component that ran for longer than
// Max before failing is considered healthy again, and the delay resets.
Max time.Duration
// MaxRestarts limits consecutive restarts; 0 means unlimited.
MaxRestarts int
}
Backoff configures restarts for RestartOnFailure.
type Component ¶
type Component interface {
// Name identifies the component in logs and status; unique per app.
Name() string
// Run does the work until ctx is canceled or the work is done.
Run(ctx context.Context) error
}
Component is a long-running unit of work managed by a Supervisor: an HTTP server, a queue worker pool, a pub/sub listener, the scheduler, or an ad-hoc background task.
Run must block until the work is finished or ctx is canceled. When ctx is canceled, Run should stop taking new work, finish or hand back in-flight work, and return promptly. Returning nil means the component completed normally; returning an error (or panicking) is a failure handled according to the component's Restart policy.
type ComponentStatus ¶
type ComponentStatus struct {
Name string // the component's name
Roles []string // its roles
Stage Stage // its shutdown stage
Restart Restart // its restart policy
State State // what it is doing
Restarts int // restarts performed so far
LastError error // most recent failure, if any
Since time.Time // when State was entered
}
ComponentStatus is a point-in-time snapshot of one component.
type Options ¶
type Options struct {
// Logger receives lifecycle, failure and restart events.
// Default slog.Default().
Logger *slog.Logger
// ShutdownTimeout bounds graceful shutdown across all stages. Default 30s.
ShutdownTimeout time.Duration
}
Options configures a Supervisor.
type PanicError ¶
type PanicError struct {
Value any // the value passed to panic
Stack []byte // the goroutine's stack when it panicked
}
PanicError is the failure recorded when a component panics.
func (*PanicError) Error ¶
func (e *PanicError) Error() string
Error implements the error interface.
type Readier ¶
type Readier interface {
// Ready reports whether the component can take work.
Ready() bool
}
Readier is optionally implemented by components that need time to become ready (for example, an HTTP server that must bind its port). Until Ready returns true, Supervisor.Ready reports false.
type Restart ¶
type Restart int
Restart decides what happens when a component fails (returns an error or panics) while the supervisor is running.
const ( // RestartNever logs the failure and leaves the component stopped. The // rest of the application keeps running. RestartNever Restart = iota // RestartOnFailure restarts the component after an exponential backoff. // If Backoff.MaxRestarts is exceeded, the failure escalates as if the // policy were StopOnFailure. RestartOnFailure // StopOnFailure shuts the whole application down; [Supervisor.Run] // returns the component's error. Use it for components the app cannot // work without, such as the HTTP server. StopOnFailure )
type Spec ¶
type Spec struct {
// Component is what runs.
Component Component
// Roles lists the roles this component belongs to (e.g. "http",
// "workers"). A component with no roles runs in every process.
Roles []string
// Stage orders shutdown: lower stages stop first.
Stage Stage
// Restart says what happens when Run fails (returns an error or
// panics); a nil return is always done.
Restart Restart
// Backoff spaces restarts; the zero value uses the defaults.
Backoff Backoff
}
Spec describes how a component is supervised.