Files
probo/contrib/claude/go-service.md
Bryan Frimin 76e6d5a9a7 Move Go service orchestration to contrib/claude
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-15 15:04:33 +01:00

1.9 KiB

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.

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