Documentation
¶
Overview ¶
Package life provides a minimal and strictly-defined lifecycle controller for goroutines.
The core goal of this package is NOT to "gracefully stop goroutines", but to enforce a set of hard concurrency invariants around goroutine admission and shutdown:
- Goroutines may only be started via TryGo.
- Once shutdown begins, all new TryGo calls are rejected.
- ShutdownAndWait waits only for goroutines that actually return.
- sync.WaitGroup.Add is never called concurrently with Wait.
IMPORTANT DISCLAIMER:
Life DOES NOT guarantee that goroutines will terminate. Goroutine termination is cooperative and entirely the responsibility of the caller. Goroutines must observe the provided context and return in a timely manner.
If a goroutine ignores the context, blocks indefinitely, or leaks, ShutdownAndWait will block indefinitely as well.
This package intentionally does not attempt to forcibly stop goroutines. It only provides correct accounting, ordering, and shutdown signaling.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrShuttingDown = errors.New("life shutting down")
ErrShuttingDown is returned by TryGo when the lifecycle has already entered shutdown state.
Once this error is returned, no new goroutines will be started for the lifetime of the Life instance.
Functions ¶
This section is empty.
Types ¶
type Life ¶
type Life struct {
// contains filtered or unexported fields
}
Life manages the lifecycle boundaries of a group of goroutines.
Life guarantees *admission correctness* and *shutdown ordering*, but explicitly does NOT guarantee goroutine termination.
All goroutines started via TryGo:
- Share the same root lifecycle context.
- Are counted exactly once in the internal WaitGroup.
- Will be waited for during shutdown *only if they return*.
Life enforces a strict separation between:
- The "running" phase, where new goroutines may be admitted.
- The "shutdown" phase, where no new goroutines are allowed and the system waits for existing ones to exit.
The design ensures full compliance with sync.WaitGroup's contract: WaitGroup.Add is never called concurrently with Wait.
func NewLife ¶
NewLife creates a new Life instance with a root lifecycle context.
The returned Life derives its root context from the provided parent. Cancellation of either the parent context or the Life itself will transition the lifecycle into shutdown state.
NewLife does not start any goroutines. Goroutines are only created via TryGo after construction.
The caller is responsible for eventually calling ShutdownAndWait to release resources and wait for managed goroutines to return.
func (*Life) LifeCtx ¶
LifeCtx returns the root lifecycle context.
The returned context is canceled when ShutdownAndWait is called. Goroutines are expected to observe ctx.Done() and exit cooperatively.
func (*Life) ShutdownAndWait ¶
func (l *Life) ShutdownAndWait()
ShutdownAndWait initiates shutdown and blocks until all lifecycle-managed goroutines have returned.
The shutdown sequence is:
- Cancel the root context, signaling all goroutines to stop.
- Acquire the exclusive lock, blocking all concurrent TryGo calls and waiting for in-flight TryGo calls to finish Add.
- Call WaitGroup.Wait after no further Add calls are possible.
NOTE:
ShutdownAndWait does NOT forcibly stop goroutines. If any goroutine fails to return (e.g., ignores context cancellation or blocks indefinitely), this method will block indefinitely.
func (*Life) TryGo ¶
TryGo attempts to start a new goroutine bound to the lifecycle.
If the lifecycle is already shutting down, TryGo returns ErrShuttingDown and the function is not executed.
The provided function receives the root lifecycle context. The function is expected to observe ctx.Done() and return.
TryGo guarantees:
- No goroutine is started after shutdown begins.
- WaitGroup.Add is never called concurrently with Wait.
- Unless ShutdownAndWait is called concurrently, TryGo is non-blocking and returns immediately.
TryGo DOES NOT guarantee that the goroutine will exit; correct shutdown behavior requires cooperation from the function.