Help us shape the future of Go! Take the 2026 Go Developer Survey

lifecycle

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: BSD-3-Clause Imports: 7 Imported by: 0

Documentation

Overview

Package lifecycle supervises ordered module setup, concurrent services and explicitly admitted workers within one shutdown budget. It owns cancellation and reverse teardown, not signal subscriptions, process exit or raw goroutines. Callbacks and the injected logger must cooperate: abandonment bounds Run's return, but cannot kill callbacks or reclaim their resources.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"log/slog"
	"os"
	"syscall"

	"go.auvem.com/corestack/lifecycle"
)

func main() {
	signals := make(chan os.Signal, 2)
	app, err := lifecycle.New(lifecycle.Config{Logger: slog.New(slog.NewTextHandler(io.Discard, nil)), Signals: signals})
	if err != nil {
		panic(err)
	}
	ready := make(chan struct{}, 2)
	for _, name := range []string{"daemon", "muxer"} {
		err := app.Register(lifecycle.Module{
			Name: name,
			Setup: func(ctx context.Context) error {
				return app.Go(ctx, name+" worker", func(ctx context.Context) error { <-ctx.Done(); return ctx.Err() })
			},
			Run:      func(ctx context.Context) error { ready <- struct{}{}; <-ctx.Done(); return ctx.Err() },
			Teardown: func(context.Context) error { return nil },
		})
		if err != nil {
			panic(err)
		}
	}
	go func() { <-ready; <-ready; signals <- syscall.SIGTERM }()
	fmt.Println(app.Run(context.Background()))
}
Output:
<nil>

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

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

App is a single-use coordinator constructed by New. Do not copy it. Register modules before Run; Go may be called concurrently during setup and running. App stores no context. After abandonment, callers own process exit and must not reuse resources whose callbacks have not returned.

func New

func New(config Config) (*App, error)

New validates and captures config without subscribing to signals or starting work.

func (*App) Go

func (a *App) Go(ctx context.Context, name string, fn func(context.Context) error) error

Go immediately launches and tracks fn, or returns an admission error without launching it. ctx must be a callback's lifecycle context or a descendant; ancestry is a caller precondition and cannot generally be checked. Detached contexts forfeit graceful cancellation. Names are diagnostic and may repeat. Callers must handle rejection; raw goroutines are outside App's guarantee.

func (*App) Register

func (a *App) Register(module Module) error

Register captures a uniquely named module with required setup and teardown. Registration closes permanently when Run begins, including a failed run.

func (*App) Run

func (a *App) Run(parent context.Context) error

Run sets up modules in registration order, then runs services concurrently. Every service and admitted worker must finish for normal completion. The first failure, parent cancellation or signal cancels their shared context and closes admission before reverse teardown. A fresh context retains parent values and gives teardown and callback completion one deadline from the shutdown trigger. In-flight setup is awaited within that budget before rollback; abandoned setup is never torn down later. Deadline or second signal abandons outstanding work. Observed failures are joined; expected callback cancellation during established shutdown is omitted only for cancellation-only error trees. Mixed errors remain intact to preserve wrapper types, identity and matching, so may still match cancellation. Initiating failures and every teardown error remain. Cancellation is omitted only when context.Cause proves App caused it; parent propagation and independently canceled descendants are retained conservatively. Run never recovers panics, closes Signals or exits the process.

type Config

type Config struct {
	// Logger receives lifecycle diagnostics and must not block.
	Logger *slog.Logger
	// Signals is a caller-owned, filtered signal source.
	Signals <-chan os.Signal
	// ShutdownTimeout bounds all shutdown work together.
	ShutdownTimeout time.Duration
}

Config supplies application policy. Logger is required and must not block. Zero ShutdownTimeout selects 30 seconds; negative values are invalid. The caller owns Signals, its subscription and cleanup, filtering to SIGINT and SIGTERM and buffering at least two signals. Nil or closed disables reception.

type Module

type Module struct {
	// Name identifies the module in errors.
	Name string
	// Setup acquires resources before any service starts.
	Setup func(context.Context) error
	// Teardown releases resources after successful Setup.
	Teardown func(context.Context) error
	// Run optionally serves until completion or cancellation.
	Run func(context.Context) error
}

Module describes one resource owner. Setup acquires resources; Teardown releases them after successful setup. A failing Setup owns its partial cleanup. Optional Run starts only after all setups succeed. Callbacks must honor cancellation.

Directories

Path Synopsis
Package cli runs caller-owned urfave/cli trees inside selected lifecycle modules.
Package cli runs caller-owned urfave/cli trees inside selected lifecycle modules.

Jump to

Keyboard shortcuts

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