Documentation
¶
Overview ¶
Package lifecycle gives a module three moments — init, ready, shutdown — and the signal handling that makes shutdown actually happen.
The ordering rule is the whole point. Hooks run in registration order going up and in REVERSE registration order coming down, so a module can safely assume that anything it was wired after is still alive while it drains.
Index ¶
- Constants
- Variables
- func Run(ctx context.Context, r *Registry, serve func() error, ...) error
- type Hook
- type Initializer
- type Ready
- type Registry
- func (r *Registry) Add(h Hook)
- func (r *Registry) AddReload(name string, fn func(context.Context) error)
- func (r *Registry) Init(ctx context.Context) error
- func (r *Registry) Names() []string
- func (r *Registry) Observe(name string, v any)
- func (r *Registry) Ready(ctx context.Context) error
- func (r *Registry) Reload(ctx context.Context) error
- func (r *Registry) Shutdown(ctx context.Context) error
- type Reloader
- type Shutdowner
Constants ¶
const DefaultDrainTimeout = 25 * time.Second
DefaultDrainTimeout is how long Run waits for in-flight work after a signal.
Variables ¶
Signals are the signals Run treats as "shut down cleanly".
Functions ¶
func Run ¶
func Run(ctx context.Context, r *Registry, serve func() error, stop func(context.Context) error, drain time.Duration) error
Run is the standard main loop: initialise, serve, wait for a signal, drain.
- serve blocks until the listener stops. A nil return means an intentional stop; an error means the listener died and the process should exit non-zero.
- stop is called once a signal arrives, and must make serve return.
The drain context is a FRESH one with its own deadline, not a child of the cancelled parent. Deriving it from the cancelled context is the classic bug: every shutdown hook gets a context that is already done and skips its work.
Types ¶
type Hook ¶
type Hook struct {
Name string
Init func(ctx context.Context) error
Ready func(ctx context.Context) error
Shutdown func(ctx context.Context) error
Reload func(ctx context.Context) error
}
Hook is one named participant in the lifecycle. A hook need only implement the phases it cares about.
type Initializer ¶
Initializer runs after the container is wired and before the server accepts traffic. Open pools, warm caches, verify a dependency answers.
An error here fails the boot. That is intended: a service that cannot reach its database should not report healthy and serve 500s.
type Ready ¶
Ready runs after the listener is up. Start background loops here, not in OnInit — a reconciler that begins before the process is serving will race the boot it is part of.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry collects hooks and runs each phase in the right order.
The zero value is ready to use.
func (*Registry) Add ¶
Add registers a hook. Order matters: later hooks initialise after earlier ones and shut down before them.
func (*Registry) AddReload ¶ added in v1.1.0
AddReload registers a named reload callback without making it a lifecycle participant. This is useful for configuration loaders that do not own a resource to initialise or shut down.
func (*Registry) Init ¶
Init runs every Init hook in registration order and STOPS at the first failure, returning it.
It stops rather than continuing because the hooks after a failed one were written assuming it succeeded. Whatever did initialise is recorded, so a following Shutdown unwinds exactly that much and no more.
func (*Registry) Observe ¶
Observe registers whichever lifecycle interfaces v implements. Pass a module or a provider and the registry works out what it participates in; passing something that implements none is a no-op, not an error.
func (*Registry) Ready ¶
Ready runs every Ready hook in registration order. Unlike Init it runs them ALL and joins the errors: the process is already serving, and refusing to start a second background loop because the first one stuttered helps nobody.
type Reloader ¶ added in v1.1.0
Reloader refreshes runtime configuration after SIGHUP or an explicit Application.Reload call. Reload failures are reported and the process keeps serving with the last known-good configuration.
type Shutdowner ¶
Shutdowner runs on the way down, in reverse registration order, under the drain deadline. Stop loops, flush buffers, close clients.