// Copyright 2022 Terin Stock. // SPDX-License-Identifier: MPL-2.0 package manager import ( "context" "sync/atomic" "golang.org/x/sync/errgroup" ) type Manager struct { started uint32 runnables []Runnable internalCtx context.Context group *errgroup.Group } func New() *Manager { return &Manager{ runnables: []Runnable{}, } } func (m *Manager) Add(r Runnable) error { if atomic.LoadUint32(&m.started) == 1 { m.group.Go(func() error { return r.Start(m.internalCtx) }) } else { m.runnables = append(m.runnables, r) } return nil } func (m *Manager) Start(ctx context.Context) error { g, internalCtx := errgroup.WithContext(ctx) m.group = g m.internalCtx = internalCtx atomic.SwapUint32(&m.started, 1) for _, r := range m.runnables { r := r g.Go(func() error { return r.Start(internalCtx) }) } m.runnables = nil return g.Wait() } type Runnable interface { Start(ctx context.Context) error }