-
Release v0.9.0 Stable
released this
2026-03-18 17:50:05 -06:00 | 1 commits to main since this releasev0.9.0
code.nochebuena.dev/go/launcherOverview
launcherorchestrates the startup and shutdown of all infrastructure components in a Go service — database pools, HTTP servers, background workers, and anything else that needs a managed lifecycle. It enforces a strict three-phase order:OnInit(open connections) →BeforeStarthooks (dependency injection wiring) →OnStart(start goroutines and listeners) → wait for OS signal or programmatic trigger →OnStopin reverse registration order. Components are never started before their dependencies are ready and never stopped before the components that depend on them.What's Included
Componentinterface —OnInit() error,OnStart() error,OnStop() errorHooktype —func() errorforBeforeStartwiring functionsOptionsstruct —ComponentStopTimeout time.Duration(default 15 s); zero value is validLauncherinterface —Append(components ...Component),BeforeStart(hooks ...Hook),Run() error,Shutdown(ctx context.Context) errorNew(logger logz.Logger, opts ...Options) Launcher— constructor; no package-level singletons or global state- OS signal handling for
SIGINTandSIGTERMbuilt intoRun - Reverse-order shutdown — components stopped in reverse registration order, each with an independent per-component timeout
Shutdown(ctx)— idempotent programmatic shutdown; safe to call from multiple goroutines
Installation
require code.nochebuena.dev/go/launcher v0.9.0Design Highlights
- The three-phase lifecycle separates resource allocation (
OnInit), dependency wiring (BeforeStart), and service activation (OnStart), ensuring no component starts serving traffic before its dependencies are ready (seedocs/adr/ADR-001-three-phase-lifecycle.md). - Shutdown runs in reverse registration order with a per-component independent timeout, so a stalled component does not block others from stopping cleanly (see
docs/adr/ADR-002-reverse-order-shutdown.md). BeforeStarthooks are the designated place for dependency injection wiring — they run after allOnInitcalls complete but before anyOnStartcall, giving access to fully initialized (but not yet started) components (seedocs/adr/ADR-003-before-start-hooks.md).Shutdownuses async.Onceto close the trigger channel, making it safe to call from multiple goroutines (e.g. a test teardown and an OS signal handler racing).
Known Limitations & Edge Cases
- There is no dependency graph between components. Registration order is the contract — callers must register dependencies before dependents and rely on reverse-order shutdown being the correct inverse. There is no cycle detection or topological sort.
OnInitcalls are sequential and not parallelised. Services with many slow-initializing components (e.g. large connection pools with health-check warmup) will experience additive startup latency.- If
OnStartfails for any component,stopAllis called immediately, but only the components whoseOnInitsucceeded will haveOnStopcalled — components that never started will still receiveOnStop. Applications should ensureOnStopis safe to call even ifOnStartwas never reached. ComponentStopTimeoutis per-component. A worst-case shutdown takesn * ComponentStopTimeoutwherenis the number of components, not a single global deadline.AppendandBeforeStartare not safe to call concurrently withRun. All registration must complete beforeRunis invoked.Shutdown(ctx)context controls the caller-side wait timeout only — it does not overrideComponentStopTimeoutfor individual components.
v0.9.0 → v1.0.0 Roadmap
- Evaluate whether parallel
OnInitis needed for services with large numbers of slow-initializing components; if so, design the concurrency model carefully to preserve clear error attribution. - Validate the reverse-order shutdown guarantee under production load, particularly with HTTP servers that need to drain in-flight requests before closing DB connections.
- Consider providing a global
Shutdowndeadline option (in addition to per-componentComponentStopTimeout) for environments where total shutdown time is bounded by an orchestrator. - Document and test the exact behaviour when
OnStopis called on a component whoseOnStartwas never reached. - Achieve production validation of
Shutdownidempotency under concurrent signal + programmatic teardown racing.
v0.9.0 rationale: The API is stable and intentional — designed through multiple architecture reviews and tested end-to-end via the todo-api POC (SQLite, RBAC, middleware stack, HTTP handlers). The module is not yet battle-tested in production for all edge cases, and the pre-1.0 designation preserves the option for minor API refinements based on real-world use.
Downloads