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 _testmain.go
*.exe *.exe
# Other Go stuff
go.mod
go.sum

View File

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

View File

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