等待执行中的任务完成后再退出进程

This commit is contained in:
余 欣怀 2023-02-13 00:29:22 +08:00
parent 2a518e8661
commit 97187ecbf9
2 changed files with 83 additions and 28 deletions

View File

@ -98,6 +98,11 @@ func (a *agent) work() {
} else { } else {
leftdata = nil leftdata = nil
inpack.a = a inpack.a = a
select {
case <-a.worker.closed:
return
default:
}
a.worker.in <- inpack a.worker.in <- inpack
if len(data) == l { if len(data) == l {
break break

View File

@ -18,16 +18,19 @@ const (
// It can connect to multi-server and grab jobs. // It can connect to multi-server and grab jobs.
type Worker struct { type Worker struct {
sync.Mutex sync.Mutex
agents []*agent agents []*agent
funcs jobFuncs funcs jobFuncs
in chan *inPack in chan *inPack
running bool running bool
ready bool ready bool
jobLeftNum int64
Id string Id string
ErrorHandler ErrorHandler ErrorHandler ErrorHandler
JobHandler JobHandler JobHandler JobHandler
limit chan bool limit chan bool
closed chan struct{}
leftJobs chan struct{}
} }
// New returns a worker. // New returns a worker.
@ -147,14 +150,20 @@ func (worker *Worker) handleInPack(inpack *inPack) {
inpack.a.Grab() inpack.a.Grab()
case dtJobAssign, dtJobAssignUniq: case dtJobAssign, dtJobAssignUniq:
go func() { go func() {
if err := worker.exec(inpack); err != nil { go func() {
worker.err(err) worker.incrExecJobNum()
defer func() {
worker.decrExecJobNum()
}()
if err := worker.exec(inpack); err != nil {
worker.err(err)
}
}()
if worker.limit != nil {
worker.limit <- true
} }
inpack.a.Grab()
}() }()
if worker.limit != nil {
worker.limit <- true
}
inpack.a.Grab()
case dtError: case dtError:
worker.err(inpack.Err()) worker.err(inpack.Err())
fallthrough fallthrough
@ -204,10 +213,22 @@ func (worker *Worker) Work() {
for _, a := range worker.agents { for _, a := range worker.agents {
a.Grab() a.Grab()
} }
// 执行任务(阻塞)
var inpack *inPack var inpack *inPack
for inpack = range worker.in { for inpack = range worker.in {
worker.handleInPack(inpack) worker.handleInPack(inpack)
} }
// 关闭Worker进程后 等待任务完成后退出
worker.Lock()
leftJobNum := int(worker.jobLeftNum)
worker.Unlock()
if worker.leftJobs != nil {
for i := 0; i < leftJobNum; i++ {
<-worker.leftJobs
}
}
worker.Reset()
worker.close()
} }
// custome handling warper // custome handling warper
@ -223,12 +244,21 @@ func (worker *Worker) customeHandler(inpack *inPack) {
func (worker *Worker) Close() { func (worker *Worker) Close() {
worker.Lock() worker.Lock()
defer worker.Unlock() defer worker.Unlock()
if worker.running == true { if worker.running == true && worker.closed == nil {
for _, a := range worker.agents { worker.closed = make(chan struct{}, 1)
a.Close() worker.closed <- struct{}{}
}
worker.running = false worker.running = false
close(worker.in) close(worker.in)
// 创建关闭后执行中的任务列表
if worker.jobLeftNum != 0 {
worker.leftJobs = make(chan struct{}, worker.jobLeftNum+int64(len(worker.in)))
}
}
}
func (worker *Worker) close() {
for _, a := range worker.agents {
a.Close()
} }
} }
@ -258,6 +288,23 @@ func (worker *Worker) SetId(id string) {
worker.broadcast(outpack) worker.broadcast(outpack)
} }
func (worker *Worker) incrExecJobNum() int64 {
worker.Lock()
defer worker.Unlock()
worker.jobLeftNum++
return worker.jobLeftNum
}
func (worker *Worker) decrExecJobNum() int64 {
worker.Lock()
defer worker.Unlock()
worker.jobLeftNum--
if worker.jobLeftNum < 0 {
worker.jobLeftNum = 0
}
return worker.jobLeftNum
}
// 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() {
@ -283,22 +330,25 @@ func (worker *Worker) exec(inpack *inPack) (err error) {
} else { } else {
r = execTimeout(f.f, inpack, time.Duration(f.timeout)*time.Second) r = execTimeout(f.f, inpack, time.Duration(f.timeout)*time.Second)
} }
if worker.running { //if worker.running {
outpack := getOutPack() outpack := getOutPack()
if r.err == nil { if r.err == nil {
outpack.dataType = dtWorkComplete outpack.dataType = dtWorkComplete
} else {
if len(r.data) == 0 {
outpack.dataType = dtWorkFail
} else { } else {
if len(r.data) == 0 { outpack.dataType = dtWorkException
outpack.dataType = dtWorkFail
} else {
outpack.dataType = dtWorkException
}
err = r.err
} }
outpack.handle = inpack.handle err = r.err
outpack.data = r.data
inpack.a.Write(outpack)
} }
outpack.handle = inpack.handle
outpack.data = r.data
err = inpack.a.Write(outpack)
if worker.leftJobs != nil {
worker.leftJobs <- struct{}{}
}
//}
return return
} }
func (worker *Worker) reRegisterFuncsForAgent(a *agent) { func (worker *Worker) reRegisterFuncsForAgent(a *agent) {