All v0.9.0 roadmap items validated in production (reverse-order shutdown, Shutdown idempotency via sync.Once, OnStop behavior when OnStart was never reached). No API changes. Bumps logz dependency from v0.9.0 to v1.0.0. API committed as stable.
44 lines
3.1 KiB
Markdown
44 lines
3.1 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to this module will be documented in this file.
|
||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||
and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||
|
||
## [1.0.0] — 2026-05-12
|
||
|
||
### Changed
|
||
|
||
- `logz` dependency bumped from v0.9.0 to v1.0.0.
|
||
|
||
### Unchanged
|
||
|
||
All existing API (`Component`, `Hook`, `Options`, `Launcher`, `New`) is
|
||
API-compatible with v0.9.0.
|
||
|
||
[1.0.0]: https://code.nochebuena.dev/go/launcher/releases/tag/v1.0.0
|
||
|
||
## [0.9.0] - 2026-03-18
|
||
|
||
### Added
|
||
|
||
- `Component` interface — `OnInit() error` (open connections, allocate resources), `OnStart() error` (start background goroutines and listeners), `OnStop() error` (graceful shutdown and resource release)
|
||
- `Hook` type — `func() error` used to register dependency-injection wiring functions that run between `OnInit` and `OnStart`
|
||
- `Options` struct — `ComponentStopTimeout time.Duration` (maximum time allowed for each component's `OnStop`; default 15 seconds); zero value is valid
|
||
- `Launcher` interface — `Append(components ...Component)`, `BeforeStart(hooks ...Hook)`, `Run() error`, `Shutdown(ctx context.Context) error`
|
||
- `New(logger logz.Logger, opts ...Options) Launcher` — constructs a `Launcher`; no package-level singletons or global state; variadic opts apply the first element if provided
|
||
- `Launcher.Append` — registers one or more components in order; startup proceeds in registration order, shutdown in reverse
|
||
- `Launcher.BeforeStart` — registers hooks that run after all `OnInit` calls complete and before any `OnStart` call; correct place for dependency injection wiring
|
||
- `Launcher.Run() error` — executes the full lifecycle (OnInit → BeforeStart hooks → OnStart → wait → reverse-order OnStop); blocks until `SIGINT`, `SIGTERM`, or `Shutdown` is called
|
||
- `Launcher.Shutdown(ctx context.Context) error` — triggers a graceful shutdown programmatically and waits for `Run` to return; idempotent via `sync.Once`, safe to call from multiple goroutines; ctx controls the caller-side wait timeout only
|
||
- OS signal handling for `SIGINT` and `SIGTERM` built into `Run` with automatic `signal.Stop` cleanup on return
|
||
- Per-component independent stop timeout: each component's `OnStop` runs in its own goroutine and is abandoned (with an error log) if it exceeds `ComponentStopTimeout`
|
||
|
||
### Design Notes
|
||
|
||
- The three-phase lifecycle (OnInit / BeforeStart / OnStart) cleanly separates resource allocation from dependency wiring from service activation, ensuring no component begins serving traffic before all its dependencies are fully initialized.
|
||
- Shutdown runs in strict reverse registration order with a per-component independent timeout, so a stalled component cannot block others from stopping; worst-case shutdown time is `n × ComponentStopTimeout`.
|
||
- `Shutdown` closes a channel via `sync.Once` rather than using a mutex or flag, making it genuinely safe to call concurrently from an OS signal handler and a test teardown racing against each other.
|
||
|
||
[0.9.0]: https://code.nochebuena.dev/go/launcher/releases/tag/v0.9.0
|