package worker import ( "context" "errors" "fmt" "sync" ) type ( // Worker should watch for context Worker interface { Start(context.Context) error } Work struct { Name string Worker Worker } WorkerPool struct { workers []*Work } ) func NewWorkerPool() *WorkerPool { return &WorkerPool{} } func (self *WorkerPool) AddWorker(name string, worker Worker) { self.workers = append(self.workers, &Work{ Name: name, Worker: worker, }) } func (self *WorkerPool) Start(ctx context.Context) { var wg sync.WaitGroup wg.Add(len(self.workers)) for _, w := range self.workers { go func(w *Work) { defer wg.Done() if err := w.Worker.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { fmt.Println("Processes finished, error", w.Name, err.Error()) } else { fmt.Println(w.Name, "done") } }(w) } wg.Wait() }