lifecycle: ordered startup, supervised services and clean shutdown #5

Closed
opened 2026-10-26 22:16:24 -07:00 by end · 1 comment
Owner

Root-module package go.auvem.com/corestack/lifecycle. Lark Relay's daemons and muxer need it first.

Clean-room rewrite. Build from this spec. Don't read or port gitea.auvem.com/go-toolkit/app.

Purpose

Ordered startup and clean shutdown for Go services and daemons, including processes that supervise several long-running services.

Requirements

  • Modules. Each module has a name, Setup(ctx) error, Teardown(ctx) error, and an optional Run(ctx) error for long-running services.
  • Startup order. Modules start in registration order. Keep it that simple unless a requirement below can't be met without declaring dependencies.
  • Setup failure. If any Setup fails, tear down only the modules already set up, in reverse order, then return.
  • Services.
    • Services run concurrently.
    • The first service error, or a SIGINT/SIGTERM, cancels the shared context so every service stops.
  • Teardown.
    • Teardown runs in reverse order under an overall deadline: configurable, with a sensible default.
    • A second signal during shutdown abandons the remaining teardown and returns.
    • All teardown errors are returned (errors.Join), not just the first.
  • Signals come from an injectable source, so tests don't send real signals.
  • Logging goes through an injected *slog.Logger. No globals and no init side effects.
  • Out of scope:
    • CLI integration; that's lifecycle/cli (separate issue).
    • Dependencies outside the standard library, unless the PR justifies them.

Done when

  • Tests pass with -race and cover:
    • startup and teardown order;
    • rollback after a partial setup;
    • one service failure stopping the others;
    • the teardown deadline;
    • a second signal abandoning teardown;
    • joined errors.
  • A package Example test shows a program with two services.
  • The package doc comment states the purpose and boundaries, and every exported item is documented.
Kickoff prompt
Use the feature-delivery skill to resolve corestack/go#5
(read the issue body; it is the spec). Repo ~/Projects/corestack/go, base main,
branch feat/lifecycle. Read AGENTS.md and the accepted ADRs first. Clean-room: do not
read or port go-toolkit/app. Independent review before the PR. 
Root-module package `go.auvem.com/corestack/lifecycle`. Lark Relay's daemons and muxer need it first. **Clean-room rewrite.** Build from this spec. Don't read or port `gitea.auvem.com/go-toolkit/app`. ## Purpose Ordered startup and clean shutdown for Go services and daemons, including processes that supervise several long-running services. ## Requirements - **Modules.** Each module has a name, `Setup(ctx) error`, `Teardown(ctx) error`, and an optional `Run(ctx) error` for long-running services. - **Startup order.** Modules start in registration order. Keep it that simple unless a requirement below can't be met without declaring dependencies. - **Setup failure.** If any Setup fails, tear down only the modules already set up, in reverse order, then return. - **Services.** - Services run concurrently. - The first service error, or a SIGINT/SIGTERM, cancels the shared context so every service stops. - **Teardown.** - Teardown runs in reverse order under an overall deadline: configurable, with a sensible default. - A second signal during shutdown abandons the remaining teardown and returns. - All teardown errors are returned (`errors.Join`), not just the first. - **Signals** come from an injectable source, so tests don't send real signals. - **Logging** goes through an injected `*slog.Logger`. No globals and no init side effects. - **Out of scope:** - CLI integration; that's `lifecycle/cli` (separate issue). - Dependencies outside the standard library, unless the PR justifies them. ## Done when - Tests pass with `-race` and cover: - startup and teardown order; - rollback after a partial setup; - one service failure stopping the others; - the teardown deadline; - a second signal abandoning teardown; - joined errors. - A package `Example` test shows a program with two services. - The package doc comment states the purpose and boundaries, and every exported item is documented. <details> <summary>Kickoff prompt</summary> ```text Use the feature-delivery skill to resolve corestack/go#5 (read the issue body; it is the spec). Repo ~/Projects/corestack/go, base main, branch feat/lifecycle. Read AGENTS.md and the accepted ADRs first. Clean-room: do not read or port go-toolkit/app. Independent review before the PR. ``` </details>
end added a new dependency 2026-10-26 22:17:23 -07:00
Author
Owner

One key additional requirement that I think we need to meet. Lifecycle needs to provide the necessary coordination to allow for a bounded, graceful shutdown that cleans up the entire app. This means we'll need to explicitly provide a tooling abstraction to manage the lifecycle of background goroutines / workers, etc.

One key additional requirement that I think we need to meet. Lifecycle needs to provide the necessary coordination to allow for a bounded, graceful shutdown that cleans up the entire app. This means we'll need to explicitly provide a tooling abstraction to manage the lifecycle of background goroutines / workers, etc.
end closed this issue 2026-10-27 15:01:51 -07:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Reference: corestack/go#5