- handle panic in routine pool.

This commit is contained in:
gazebo
2018-06-29 09:18:09 +08:00
parent 3b36c74a29
commit 8c4e92f5ef
2 changed files with 21 additions and 11 deletions

View File

@@ -4,8 +4,6 @@ import (
"crypto/md5" "crypto/md5"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"git.rosy.net.cn/baseapi"
) )
const ( const (
@@ -44,19 +42,28 @@ func New(minRoutineCount, maxRoutineCount int) *Pool {
return retVal return retVal
} }
func callHandler(handler func()) (retVal interface{}) {
defer func() {
if r := recover(); r != nil {
retVal = r
}
}()
handler()
return retVal
}
func taskFun(taskChan chan *TaskParam, index int) { func taskFun(taskChan chan *TaskParam, index int) {
for { for {
taskParam := <-taskChan taskParam := <-taskChan
baseapi.SugarLogger.Debugf("routine:%d, handle task:%v", index, taskParam.handler) // baseapi.SugarLogger.Debugf("routine:%d, handle task:%v", index, taskParam.handler)
taskParam.handler() taskParam.resultChan <- callHandler(taskParam.handler)
taskParam.resultChan <- ""
} }
} }
func (p *Pool) CallFun(func4Call func(), primaryID string) { func (p *Pool) CallFun(func4Call func(), primaryID string) {
if p.curRoutineCount > 0 { if p.curRoutineCount > 0 {
result := md5.Sum([]byte(primaryID)) result := md5.Sum([]byte(primaryID))
resultInt64 := int64(binary.LittleEndian.Uint32(result[:8])) resultInt64 := int64(binary.LittleEndian.Uint32(result[8:]))
chanIndex := int(resultInt64 % int64(p.curRoutineCount)) chanIndex := int(resultInt64 % int64(p.curRoutineCount))
chanParam := &TaskParam{ chanParam := &TaskParam{
@@ -64,7 +71,10 @@ func (p *Pool) CallFun(func4Call func(), primaryID string) {
resultChan: make(chan interface{}), resultChan: make(chan interface{}),
} }
p.taskChans[chanIndex] <- chanParam p.taskChans[chanIndex] <- chanParam
_ = <-chanParam.resultChan r := <-chanParam.resultChan
if r != nil {
panic(r)
}
} else { } else {
func4Call() func4Call()
} }

View File

@@ -23,12 +23,12 @@ func init() {
} }
func TestCallFun(t *testing.T) { func TestCallFun(t *testing.T) {
pool := New(10, 10) pool := New(1000, 1000)
for i := 0; i < 20; i++ { for i := 0; i < 200; i++ {
x := rand.Int()
pool.CallFun(func() { pool.CallFun(func() {
x := i
sugarLogger.Debug(x) sugarLogger.Debug(x)
}, utils.Int2Str(i)) }, utils.Int2Str(x))
} }
pool.CallFun(func() { pool.CallFun(func() {
sugarLogger.Debug(15) sugarLogger.Debug(15)