package main
import (
"fmt"
"time"
)
type Worker struct {
id int
err error
}
type WorkManager struct {
workerChan chan *Worker
nWorkers int
}
func NewWorkerManager(nworkers int) *WorkManager {
return &WorkManager{
nWorkers: nworkers,
workerChan: make(chan *Worker, nworkers),
}
}
func (wm *WorkManager) StartWorkerPool() {
for i := 0; i < wm.nWorkers; i++ {
i := i
wk := Worker{
id: i,
err: nil,
}
go wk.work(wm.workerChan)
}
wm.KeepLiveWorkers()
}
func (wm *WorkManager) KeepLiveWorkers() {
for wk := range wm.workerChan {
fmt.Printf("wk.id: %v\n", wk.id)
fmt.Printf("wk.err: %v\n", wk.err)
wk.err = nil
go wk.work(wm.workerChan)
}
}
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 happend with [ %v ]", r)
}
} else {
wk.err = err
}
workerChan <- wk
}()
fmt.Printf("wk.id: %v\n", wk.id)
for i := 0; i < 5; i++ {
time.Sleep(time.Second * 1)
}
panic("work panic")
return err
}
func main() {
wm := NewWorkerManager(100000000)
wm.StartWorkerPool()
}