package driver import ( "context" "errors" "fmt" "io" "log/slog" "net" "sync" "syscall" ) // Run starts the explicit driver list and waits for every driver to stop. A // failure cancels the other drivers. Reconnect notifications request fresh // snapshots. A nil or closed connected channel disables notifications. An empty // list waits for cancellation. Only this runner logs driver failures. func Run(ctx context.Context, drivers []Driver, connected <-chan struct{}) error { ctx, cancel := context.WithCancel(ctx) defer cancel() if len(drivers) == 0 { <-ctx.Done() return nil } results := make(chan driverResult, len(drivers)) var workers sync.WaitGroup for index, integration := range drivers { workers.Go(func() { results <- driverResult{ index: index, err: integration.Run(ctx), } }) } defer workers.Wait() var failures []error for remaining := len(drivers); remaining > 0; { select { case _, open := <-connected: if !open { connected = nil continue } for _, integration := range drivers { integration.Refresh() } case result := <-results: remaining-- if result.err == nil || ctx.Err() != nil && stopOnly(result.err, ctx.Err()) { continue } slog.Error("driver failed", "driver", result.index, "err", result.err) failures = append(failures, fmt.Errorf("run driver %d: %w", result.index, result.err)) cancel() } } return errors.Join(failures...) } type driverResult struct { index int err error } func stopOnly(err error, cancellation error) bool { joined, ok := err.(interface{ Unwrap() []error }) if ok { found := false for _, cause := range joined.Unwrap() { if cause != nil { found = true if !stopOnly(cause, cancellation) { return false } } } return found } wrapped, ok := err.(interface{ Unwrap() error }) if ok { return stopOnly(wrapped.Unwrap(), cancellation) } return errors.Is(err, cancellation) || errors.Is(err, net.ErrClosed) || errors.Is(err, io.ErrClosedPipe) || errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) }