Move Go service orchestration to contrib/claude
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
53
contrib/claude/go-service.md
Normal file
53
contrib/claude/go-service.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Go Service Orchestration
|
||||
|
||||
A top-level `Run` method starts child subsystems (workers, servers) as goroutines via `sync.WaitGroup.Go`. Each child gets its own cancellable context created with `context.WithCancel(context.WithoutCancel(ctx))` so that a parent cancellation does not kill in-flight work — the parent explicitly calls each `stop*` function and then `wg.Wait()` for a controlled shutdown.
|
||||
|
||||
When a child crashes, it calls `cancel(fmt.Errorf("… crashed: %w", err))` to signal the parent.
|
||||
|
||||
```go
|
||||
func (impl *Implm) Run(ctx context.Context, l *log.Logger) error {
|
||||
wg := sync.WaitGroup{}
|
||||
ctx, cancel := context.WithCancelCause(ctx)
|
||||
defer cancel(context.Canceled)
|
||||
|
||||
// Start a worker
|
||||
workerCtx, stopWorker := context.WithCancel(context.WithoutCancel(ctx))
|
||||
worker := NewFooWorker(pgClient, l.Named("foo-worker"))
|
||||
wg.Go(
|
||||
func() {
|
||||
if err := worker.Run(workerCtx); err != nil {
|
||||
cancel(fmt.Errorf("foo worker crashed: %w", err))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// Start a server
|
||||
serverCtx, stopServer := context.WithCancel(context.WithoutCancel(ctx))
|
||||
defer stopServer()
|
||||
wg.Go(
|
||||
func() {
|
||||
if err := impl.runServer(serverCtx, l); err != nil {
|
||||
cancel(fmt.Errorf("server crashed: %w", err))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
stopServer()
|
||||
stopWorker()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return context.Cause(ctx)
|
||||
}
|
||||
```
|
||||
|
||||
## Key principles
|
||||
|
||||
- **`context.WithCancelCause`** — the parent uses this to track why it's shutting down
|
||||
- **`context.WithoutCancel`** — each child gets an independent context so parent cancellation doesn't kill in-flight work
|
||||
- **`context.WithCancel` on the detached context** — gives the parent an explicit `stop*` function for each child
|
||||
- **Crash propagation** — when a child fails, it calls `cancel(fmt.Errorf("… crashed: %w", err))` to signal the parent
|
||||
- **Ordered shutdown** — `<-ctx.Done()` triggers, then each `stop*` is called, then `wg.Wait()` blocks until all children finish
|
||||
- **`context.Cause(ctx)`** — returns the original error that caused shutdown
|
||||
Reference in New Issue
Block a user