forked from yuxh/gearman-go
		
	等待执行中的任务完成后再退出进程
This commit is contained in:
		
							parent
							
								
									2a518e8661
								
							
						
					
					
						commit
						97187ecbf9
					
				@ -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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										106
									
								
								worker/worker.go
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								worker/worker.go
									
									
									
									
									
								
							@ -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) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user