chore(queue): to handle panic cases from inside the worker (#594)
This commit is contained in:
parent
4349a17017
commit
95866bf205
|
@ -63,14 +63,25 @@ func (q *Queue) Queue(job interface{}) error {
|
||||||
return q.worker.Queue(job)
|
return q.worker.Queue(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *Queue) work(num int) {
|
||||||
|
q.routineGroup.Run(func() {
|
||||||
|
// to handle panic cases from inside the worker
|
||||||
|
// in such case, we start a new goroutine
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
logx.LogError.Error(err)
|
||||||
|
go q.work(num)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
logx.LogAccess.Info("started the worker num ", num)
|
||||||
|
q.worker.Run(q.quit)
|
||||||
|
logx.LogAccess.Info("closed the worker num ", num)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (q *Queue) startWorker() {
|
func (q *Queue) startWorker() {
|
||||||
for i := 0; i < q.workerCount; i++ {
|
for i := 0; i < q.workerCount; i++ {
|
||||||
go func(num int) {
|
go q.work(i)
|
||||||
q.routineGroup.Run(func() {
|
|
||||||
logx.LogAccess.Info("started the worker num ", num)
|
|
||||||
q.worker.Run(q.quit)
|
|
||||||
logx.LogAccess.Info("closed the worker num ", num)
|
|
||||||
})
|
|
||||||
}(i)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ var _ queue.Worker = (*Worker)(nil)
|
||||||
// Option for queue system
|
// Option for queue system
|
||||||
type Option func(*Worker)
|
type Option func(*Worker)
|
||||||
|
|
||||||
|
var errMaxCapacity = errors.New("max capacity reached")
|
||||||
|
|
||||||
// Worker for simple queue using channel
|
// Worker for simple queue using channel
|
||||||
type Worker struct {
|
type Worker struct {
|
||||||
queueNotification chan gorush.PushNotification
|
queueNotification chan gorush.PushNotification
|
||||||
|
@ -49,7 +51,7 @@ func (s *Worker) Queue(job interface{}) error {
|
||||||
case s.queueNotification <- job.(gorush.PushNotification):
|
case s.queueNotification <- job.(gorush.PushNotification):
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return errors.New("max capacity reached")
|
return errMaxCapacity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package simple
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/appleboy/gorush/gorush"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQueueUsage(t *testing.T) {
|
||||||
|
w := NewWorker()
|
||||||
|
assert.Equal(t, runtime.NumCPU()<<1, w.Capacity())
|
||||||
|
assert.Equal(t, 0, w.Usage())
|
||||||
|
|
||||||
|
w.Queue(gorush.PushNotification{})
|
||||||
|
assert.Equal(t, 1, w.Usage())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMaxCapacity(t *testing.T) {
|
||||||
|
w := NewWorker(WithQueueNum(2))
|
||||||
|
assert.Equal(t, 2, w.Capacity())
|
||||||
|
assert.Equal(t, 0, w.Usage())
|
||||||
|
|
||||||
|
assert.NoError(t, w.Queue(gorush.PushNotification{}))
|
||||||
|
assert.Equal(t, 1, w.Usage())
|
||||||
|
assert.NoError(t, w.Queue(gorush.PushNotification{}))
|
||||||
|
assert.Equal(t, 2, w.Usage())
|
||||||
|
assert.Error(t, w.Queue(gorush.PushNotification{}))
|
||||||
|
assert.Equal(t, 2, w.Usage())
|
||||||
|
|
||||||
|
err := w.Queue(gorush.PushNotification{})
|
||||||
|
assert.Equal(t, errMaxCapacity, err)
|
||||||
|
}
|
Loading…
Reference in New Issue