Added graceful stop

This commit is contained in:
Dmitry Krylov 2022-01-04 15:23:39 +03:00
parent 2263172a84
commit 9cc0c12d96
3 changed files with 28 additions and 8 deletions

4
.gitignore vendored
View File

@ -20,3 +20,7 @@ _cgo_export.*
_testmain.go
*.exe
# Other Go stuff
go.mod
go.sum

View File

@ -55,6 +55,10 @@ func (a *agent) work() {
var err error
var data, leftdata []byte
for {
if a.worker.stopped {
return
}
if data, err = a.read(); err != nil {
if opErr, ok := err.(*net.OpError); ok {
if opErr.Temporary() {
@ -91,6 +95,10 @@ func (a *agent) work() {
continue
}
for {
if a.worker.stopped {
return
}
if inpack, l, err = decodeInPack(data); err != nil {
a.worker.err(err)
leftdata = data

View File

@ -22,7 +22,9 @@ type Worker struct {
funcs jobFuncs
in chan *inPack
running bool
stopped bool
ready bool
active sync.WaitGroup
Id string
ErrorHandler ErrorHandler
@ -39,9 +41,10 @@ type Worker struct {
// OneByOne(=1), there will be only one job executed in a time.
func New(limit int) (worker *Worker) {
worker = &Worker{
agents: make([]*agent, 0, limit),
funcs: make(jobFuncs),
in: make(chan *inPack, queueSize),
agents: make([]*agent, 0, limit),
funcs: make(jobFuncs),
in: make(chan *inPack, queueSize),
stopped: false,
}
if limit != Unlimited {
worker.limit = make(chan bool, limit-1)
@ -221,11 +224,11 @@ func (worker *Worker) customeHandler(inpack *inPack) {
// Stop serving
func (worker *Worker) Stop() {
worker.Lock()
defer worker.Unlock()
if worker.running == true {
close(worker.in)
}
// Set stopped flag
worker.stopped = true
// Wait for all the running activities has stopped
worker.active.Wait()
}
// Close connection and exit main loop
@ -270,6 +273,8 @@ func (worker *Worker) SetId(id string) {
// inner job executing
func (worker *Worker) exec(inpack *inPack) (err error) {
defer func() {
worker.active.Done()
if worker.limit != nil {
<-worker.limit
}
@ -285,6 +290,9 @@ func (worker *Worker) exec(inpack *inPack) (err error) {
if !ok {
return fmt.Errorf("The function does not exist: %s", inpack.fn)
}
worker.active.Add(1)
var r *result
if f.timeout == 0 {
d, e := f.f(inpack)