initial import
This commit is contained in:
95
dq/consumernode.go
Normal file
95
dq/consumernode.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package dq
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"zero/core/logx"
|
||||
"zero/core/syncx"
|
||||
|
||||
"github.com/beanstalkd/beanstalk"
|
||||
)
|
||||
|
||||
type (
|
||||
consumerNode struct {
|
||||
conn *connection
|
||||
tube string
|
||||
on *syncx.AtomicBool
|
||||
}
|
||||
|
||||
consumeService struct {
|
||||
c *consumerNode
|
||||
consume Consume
|
||||
}
|
||||
)
|
||||
|
||||
func newConsumerNode(endpoint, tube string) *consumerNode {
|
||||
return &consumerNode{
|
||||
conn: newConnection(endpoint, tube),
|
||||
tube: tube,
|
||||
on: syncx.ForAtomicBool(true),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *consumerNode) dispose() {
|
||||
c.on.Set(false)
|
||||
}
|
||||
|
||||
func (c *consumerNode) consumeEvents(consume Consume) {
|
||||
for c.on.True() {
|
||||
conn, err := c.conn.get()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
// because getting conn takes at most one second, reserve tasks at most 5 seconds,
|
||||
// if don't check on/off here, the conn might not be closed due to
|
||||
// graceful shutdon waits at most 5.5 seconds.
|
||||
if !c.on.True() {
|
||||
break
|
||||
}
|
||||
|
||||
conn.Tube.Name = c.tube
|
||||
conn.TubeSet.Name[c.tube] = true
|
||||
id, body, err := conn.Reserve(reserveTimeout)
|
||||
if err == nil {
|
||||
conn.Delete(id)
|
||||
consume(body)
|
||||
continue
|
||||
}
|
||||
|
||||
// the error can only be beanstalk.NameError or beanstalk.ConnError
|
||||
switch cerr := err.(type) {
|
||||
case beanstalk.ConnError:
|
||||
switch cerr.Err {
|
||||
case beanstalk.ErrTimeout:
|
||||
// timeout error on timeout, just continue the loop
|
||||
case beanstalk.ErrBadChar, beanstalk.ErrBadFormat, beanstalk.ErrBuried, beanstalk.ErrDeadline,
|
||||
beanstalk.ErrDraining, beanstalk.ErrEmpty, beanstalk.ErrInternal, beanstalk.ErrJobTooBig,
|
||||
beanstalk.ErrNoCRLF, beanstalk.ErrNotFound, beanstalk.ErrNotIgnored, beanstalk.ErrTooLong:
|
||||
// won't reset
|
||||
logx.Error(err)
|
||||
default:
|
||||
// beanstalk.ErrOOM, beanstalk.ErrUnknown and other errors
|
||||
logx.Error(err)
|
||||
c.conn.reset()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
default:
|
||||
logx.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.conn.Close(); err != nil {
|
||||
logx.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cs consumeService) Start() {
|
||||
cs.c.consumeEvents(cs.consume)
|
||||
}
|
||||
|
||||
func (cs consumeService) Stop() {
|
||||
cs.c.dispose()
|
||||
}
|
||||
Reference in New Issue
Block a user