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 wg sync.WaitGroup } ) 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) { for _, w := range self.workers { self.wg.Add(1) go func(w *Work) { defer self.wg.Done() if err := w.Worker.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { fmt.Println("Error ", w.Name, err.Error()) } else { fmt.Println(w.Name, "done") } }(w) } } func (self *WorkerPool) Wait() { self.wg.Wait() }