lifecycle

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 14, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package lifecycle hosts process startup, readiness, and graceful shutdown.

A Coordinator's life divides into an inert declaration phase and a single blocking call that owns everything after. While waiting, the registration calls — Coordinator.OnStartup, Coordinator.OnShutdown, Coordinator.OnReady, Coordinator.Monitor — declare what starting, draining, becoming ready, and runtime failure mean for this service; nothing executes. Coordinator.Run then drives the whole sequence and returns one joined error. Internally the coordinator moves WAITING → STARTING → RUNNING → DRAINING → STOPPED; registration is legal only while waiting, Run exactly once, and each violation panics — a late registration is a programming error, not a runtime condition.

Context ownership

The caller owns the signal context: a composition root builds one with signal.NotifyContext and passes it to Run. Run derives the run context — cancelled by the signal, by a monitored failure, or when Run ends — and passes it to every startup hook; work that outlives its hook keeps watching that context. The coordinator installs no signal handlers of its own.

Startup and readiness

Run launches every startup hook concurrently and waits. If any hook returns an error, the coordinator drains what did start and Run returns the joined failures wrapped "startup:" — readiness never flips, so a probe backed by Coordinator.Ready cannot report a partially started process. On success the coordinator is ready and the OnReady hooks run synchronously, in registration order. Coordinator satisfies ReadinessChecker, the contract a /readyz endpoint consumes; readiness is non-monotonic, false again the moment draining begins.

Running and monitors

While running, Run blocks until the signal context is cancelled — the clean path — or a monitored channel yields a non-nil error, which ends the run and joins Run's return wrapped "run:". A nil received error is ignored, and a channel closing retires its watcher quietly: that is the expected end of a source that stopped cleanly.

Drain

The drain runs every shutdown hook concurrently, each passed a fresh drain context bounded by Run's timeout and derived from context.Background, so cleanup has its whole budget regardless of the cancelled run context. Hook errors join Run's return wrapped "shutdown:"; a drain that outlives the timeout adds an error wrapping context.DeadlineExceeded while the unfinished hooks continue on the expired context — the coordinator cannot stop a goroutine — so hooks that honor their context stop promptly. Run returns nil exactly when a signal-driven exit drained cleanly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Coordinator

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

Coordinator hosts a process's lifecycle. Hooks and monitors are declared while it waits; one blocking Coordinator.Run then owns the whole sequence — parallel startup, readiness, monitored running, and the timed drain.

func New

func New() *Coordinator

New returns a Coordinator awaiting registrations and Coordinator.Run.

func (*Coordinator) Monitor added in v0.3.0

func (c *Coordinator) Monitor(errs <-chan error)

Monitor registers a channel Coordinator.Run watches while running: the first non-nil error received ends the run and joins Run's return. A nil error is ignored, and a closed channel retires quietly — the expected end of a source that stopped cleanly. Registration after Run panics.

func (*Coordinator) OnReady added in v0.3.0

func (c *Coordinator) OnReady(fn func())

OnReady registers a hook Coordinator.Run invokes synchronously, in registration order, once every startup hook has succeeded. Registration after Run panics.

func (*Coordinator) OnShutdown

func (c *Coordinator) OnShutdown(fn func(context.Context) error)

OnShutdown registers a hook the drain runs concurrently with every other shutdown hook, passing a fresh drain context bounded by Run's timeout. Errors join Coordinator.Run's return. Registration after Run panics.

func (*Coordinator) OnStartup

func (c *Coordinator) OnStartup(fn func(context.Context) error)

OnStartup registers a hook Coordinator.Run launches concurrently with every other startup hook, passing the run context. A non-nil return fails startup. Registration after Run panics.

func (*Coordinator) Ready

func (c *Coordinator) Ready() bool

Ready reports whether the coordinator is running: true once every startup hook has succeeded, and false again the moment draining begins.

func (*Coordinator) Run added in v0.3.0

func (c *Coordinator) Run(
	ctx context.Context,
	drainTimeout time.Duration,
) error

Run drives the lifecycle and blocks until it ends. It launches the startup hooks and waits; a failure drains what did start and returns the joined errors, with readiness never flipped. Otherwise it marks the coordinator ready, invokes the OnReady hooks, and blocks until ctx is cancelled or a monitored channel yields an error. It then drains — every shutdown hook against a fresh context bounded by drainTimeout — and returns nil for a cancellation with a clean drain, or the joined startup, run, and shutdown errors otherwise. Hooks still running when the drain times out continue on the expired context, their late errors dropped. Run is legal exactly once; a second call panics.

type ReadinessChecker

type ReadinessChecker interface {
	Ready() bool
}

ReadinessChecker reports whether a subsystem is ready to serve. Coordinator satisfies it, as does any subsystem a readiness probe aggregates.

Jump to

Keyboard shortcuts

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