package main
import "fmt"
type WorkerManager struct {
workerChan chan *worker
nWorkers int
}
func NewWorkerManager(nworkers int) *WorkerManager {
return &WorkerManager{
nWorkers: nworkers,
workerChan: make(chan *worker, nworkers),
}
}
func (wm *WorkerManager) StartWorkerPool() {
for i := 0; i < wm.nWorkers; i++ {
i := i
wk := &worker{id: i}
go wk.work(wm.workerChan)
}
wm.KeepLiveWorkers()
}
func (wm *WorkerManager) KeepLiveWorkers() {
for wk := range wm.workerChan {
fmt.Printf("Worker %d stopped with err: [%v] \n", wk.id, wk.err)
wk.err = nil
go wk.work(wm.workerChan)
}
}
type worker struct {
id int
err error
}
func (wk worker) work(workerChan chan<- worker) (err error) {
defer func() {
if r := recover(); r != nil {
if err, ok := r.(error); ok {
wk.err = err
} else {
wk.err = fmt.Errorf("Panic happened with[ % v]", r)
}
} else {
wk.err = err
}
workerChan <- wk
}()
fmt.Println("Start Worker…ID = ", wk.id)
panic("worker panic..")
return err
}
func main() {
wm := NewWorkerManager(10)
wm.StartWorkerPool()
}