blocking on GRAB_JOB instead of executing blocked
This commit is contained in:
		
							parent
							
								
									3aa95042e6
								
							
						
					
					
						commit
						ddba5ab2f2
					
				@ -12,6 +12,9 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
						Unlimited = 0
 | 
				
			||||||
 | 
						OneByOne  = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Immediately = 0
 | 
						Immediately = 0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -19,7 +22,7 @@ const (
 | 
				
			|||||||
Worker side api for gearman
 | 
					Worker side api for gearman
 | 
				
			||||||
 | 
					
 | 
				
			||||||
usage:
 | 
					usage:
 | 
				
			||||||
w = worker.New()
 | 
					w = worker.New(worker.Unlimited)
 | 
				
			||||||
w.AddFunction("foobar", foobar)
 | 
					w.AddFunction("foobar", foobar)
 | 
				
			||||||
w.AddServer("127.0.0.1:4730")
 | 
					w.AddServer("127.0.0.1:4730")
 | 
				
			||||||
w.Work() // Enter the worker's main loop
 | 
					w.Work() // Enter the worker's main loop
 | 
				
			||||||
@ -34,6 +37,7 @@ func foobar(job *Job) (data []byte, err os.Error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
type Worker struct {
 | 
					type Worker struct {
 | 
				
			||||||
 | 
						sync.Mutex
 | 
				
			||||||
	agents  []*agent
 | 
						agents  []*agent
 | 
				
			||||||
	funcs   JobFuncs
 | 
						funcs   JobFuncs
 | 
				
			||||||
	in      chan *inPack
 | 
						in      chan *inPack
 | 
				
			||||||
@ -43,16 +47,19 @@ type Worker struct {
 | 
				
			|||||||
	// assign a ErrFunc to handle errors
 | 
						// assign a ErrFunc to handle errors
 | 
				
			||||||
	ErrorHandler ErrorHandler
 | 
						ErrorHandler ErrorHandler
 | 
				
			||||||
	JobHandler   JobHandler
 | 
						JobHandler   JobHandler
 | 
				
			||||||
	mutex        sync.Mutex
 | 
						limit        chan bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Get a new worker
 | 
					// Get a new worker
 | 
				
			||||||
func New() (worker *Worker) {
 | 
					func New(limit int) (worker *Worker) {
 | 
				
			||||||
	worker = &Worker{
 | 
						worker = &Worker{
 | 
				
			||||||
		agents: make([]*agent, 0),
 | 
							agents: make([]*agent, 0),
 | 
				
			||||||
		funcs:  make(JobFuncs),
 | 
							funcs:  make(JobFuncs),
 | 
				
			||||||
		in:     make(chan *inPack, QUEUE_SIZE),
 | 
							in:     make(chan *inPack, QUEUE_SIZE),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if limit != Unlimited {
 | 
				
			||||||
 | 
							worker.limit = make(chan bool, limit - 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,8 +96,8 @@ func (worker *Worker) broadcast(outpack *outPack) {
 | 
				
			|||||||
// The API will tell every connected job server that 'I can do this'
 | 
					// The API will tell every connected job server that 'I can do this'
 | 
				
			||||||
func (worker *Worker) AddFunc(funcname string,
 | 
					func (worker *Worker) AddFunc(funcname string,
 | 
				
			||||||
	f JobFunc, timeout uint32) (err error) {
 | 
						f JobFunc, timeout uint32) (err error) {
 | 
				
			||||||
	worker.mutex.Lock()
 | 
						worker.Lock()
 | 
				
			||||||
	defer worker.mutex.Unlock()
 | 
						defer worker.Unlock()
 | 
				
			||||||
	if _, ok := worker.funcs[funcname]; ok {
 | 
						if _, ok := worker.funcs[funcname]; ok {
 | 
				
			||||||
		return fmt.Errorf("The function already exists: %s", funcname)
 | 
							return fmt.Errorf("The function already exists: %s", funcname)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -120,8 +127,8 @@ func (worker *Worker) addFunc(funcname string, timeout uint32) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Remove a function.
 | 
					// Remove a function.
 | 
				
			||||||
func (worker *Worker) RemoveFunc(funcname string) (err error) {
 | 
					func (worker *Worker) RemoveFunc(funcname string) (err error) {
 | 
				
			||||||
	worker.mutex.Lock()
 | 
						worker.Lock()
 | 
				
			||||||
	defer worker.mutex.Unlock()
 | 
						defer worker.Unlock()
 | 
				
			||||||
	if _, ok := worker.funcs[funcname]; !ok {
 | 
						if _, ok := worker.funcs[funcname]; !ok {
 | 
				
			||||||
		return fmt.Errorf("The function does not exist: %s", funcname)
 | 
							return fmt.Errorf("The function does not exist: %s", funcname)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -149,9 +156,17 @@ func (worker *Worker) handleInPack(inpack *inPack) {
 | 
				
			|||||||
	case ERROR:
 | 
						case ERROR:
 | 
				
			||||||
		worker.err(GetError(inpack.data))
 | 
							worker.err(GetError(inpack.data))
 | 
				
			||||||
	case JOB_ASSIGN, JOB_ASSIGN_UNIQ:
 | 
						case JOB_ASSIGN, JOB_ASSIGN_UNIQ:
 | 
				
			||||||
		if err := worker.exec(inpack); err != nil {
 | 
							go func() {
 | 
				
			||||||
			worker.err(err)
 | 
								if err := worker.exec(inpack); err != nil {
 | 
				
			||||||
 | 
									worker.err(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
 | 
							if (worker.limit != nil) {
 | 
				
			||||||
 | 
								worker.limit <- true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inpack.a.Grab()
 | 
				
			||||||
 | 
						case ECHO_RES:
 | 
				
			||||||
 | 
							fallthrough
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		worker.customeHandler(inpack)
 | 
							worker.customeHandler(inpack)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -177,7 +192,7 @@ func (worker *Worker) Work() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	var inpack *inPack
 | 
						var inpack *inPack
 | 
				
			||||||
	for inpack = range worker.in {
 | 
						for inpack = range worker.in {
 | 
				
			||||||
		go worker.handleInPack(inpack)
 | 
							worker.handleInPack(inpack)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -225,6 +240,9 @@ func (worker *Worker) SetId(id string) {
 | 
				
			|||||||
// Execute the job. And send back the result.
 | 
					// Execute the job. And send back the result.
 | 
				
			||||||
func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
					func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
 | 
							if (worker.limit != nil) {
 | 
				
			||||||
 | 
								<-worker.limit
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
			if e, ok := r.(error); ok {
 | 
								if e, ok := r.(error); ok {
 | 
				
			||||||
				err = e
 | 
									err = e
 | 
				
			||||||
@ -259,7 +277,6 @@ func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
				
			|||||||
		outpack.handle = inpack.handle
 | 
							outpack.handle = inpack.handle
 | 
				
			||||||
		outpack.data = r.data
 | 
							outpack.data = r.data
 | 
				
			||||||
		inpack.a.write(outpack)
 | 
							inpack.a.write(outpack)
 | 
				
			||||||
		inpack.a.Grab()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user