forked from yuxh/gearman-go
		
	a better doc
This commit is contained in:
		
							parent
							
								
									02e6bfebcb
								
							
						
					
					
						commit
						298edadfa6
					
				@ -11,8 +11,8 @@ and getting responses from the server.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	import "github.com/mikespook/gearman-go/client"
 | 
						import "github.com/mikespook/gearman-go/client"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The worker package will help developers in developing Gearman worker
 | 
					The worker package will help developers to develop Gearman's worker
 | 
				
			||||||
service easily.
 | 
					in an easy way.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	import "github.com/mikespook/gearman-go/worker"
 | 
						import "github.com/mikespook/gearman-go/worker"
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					// The worker package helps developers to develop Gearman's worker
 | 
				
			||||||
 | 
					// in an easy way.
 | 
				
			||||||
package worker
 | 
					package worker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
@ -14,24 +16,8 @@ const (
 | 
				
			|||||||
	Immediately = 0
 | 
						Immediately = 0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Worker is the only structure needed by worker side developing.
 | 
				
			||||||
Worker side api for gearman
 | 
					// It can connect to multi-server and grab jobs.
 | 
				
			||||||
 | 
					 | 
				
			||||||
usage:
 | 
					 | 
				
			||||||
w = worker.New(worker.Unlimited)
 | 
					 | 
				
			||||||
w.AddFunction("foobar", foobar)
 | 
					 | 
				
			||||||
w.AddServer("127.0.0.1:4730")
 | 
					 | 
				
			||||||
w.Work() // Enter the worker's main loop
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The definition of the callback function 'foobar' should suit for the type 'JobFunction'.
 | 
					 | 
				
			||||||
It looks like this:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func foobar(job *Job) (data []byte, err os.Error) {
 | 
					 | 
				
			||||||
    //sth. here
 | 
					 | 
				
			||||||
    //plaplapla...
 | 
					 | 
				
			||||||
    return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
type Worker struct {
 | 
					type Worker struct {
 | 
				
			||||||
	sync.Mutex
 | 
						sync.Mutex
 | 
				
			||||||
	agents  []*agent
 | 
						agents  []*agent
 | 
				
			||||||
@ -40,13 +26,18 @@ type Worker struct {
 | 
				
			|||||||
	running bool
 | 
						running bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Id           string
 | 
						Id           string
 | 
				
			||||||
	// assign a ErrFunc to handle errors
 | 
					 | 
				
			||||||
	ErrorHandler ErrorHandler
 | 
						ErrorHandler ErrorHandler
 | 
				
			||||||
	JobHandler   JobHandler
 | 
						JobHandler   JobHandler
 | 
				
			||||||
	limit        chan bool
 | 
						limit        chan bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Get a new worker
 | 
					// Return a worker.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// If limit is set to Unlimited(=0), the worker will grab all jobs
 | 
				
			||||||
 | 
					// and execute them parallelly.
 | 
				
			||||||
 | 
					// If limit is greater than zero, the number of paralled executing
 | 
				
			||||||
 | 
					// jobs are limited under the number. If limit is assgined to
 | 
				
			||||||
 | 
					// 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),
 | 
				
			||||||
@ -59,15 +50,16 @@ func New(limit int) (worker *Worker) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					// inner error handling
 | 
				
			||||||
func (worker *Worker) err(e error) {
 | 
					func (worker *Worker) err(e error) {
 | 
				
			||||||
	if worker.ErrorHandler != nil {
 | 
						if worker.ErrorHandler != nil {
 | 
				
			||||||
		worker.ErrorHandler(e)
 | 
							worker.ErrorHandler(e)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add a server. The addr should be 'host:port' format.
 | 
					// Add a Gearman job server.
 | 
				
			||||||
// The connection is established at this time.
 | 
					//
 | 
				
			||||||
 | 
					// addr should be formated as 'host:port'.
 | 
				
			||||||
func (worker *Worker) AddServer(net, addr string) (err error) {
 | 
					func (worker *Worker) AddServer(net, addr string) (err error) {
 | 
				
			||||||
	// Create a new job server's client as a agent of server
 | 
						// Create a new job server's client as a agent of server
 | 
				
			||||||
	a, err := newAgent(net, addr, worker)
 | 
						a, err := newAgent(net, addr, worker)
 | 
				
			||||||
@ -78,9 +70,7 @@ func (worker *Worker) AddServer(net, addr string) (err error) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Write a job to job server.
 | 
					// Broadcast an outpack to all Gearman server.
 | 
				
			||||||
// Here, the job's mean is not the oraginal mean.
 | 
					 | 
				
			||||||
// Just looks like a network package for job's result or tell job server, there was a fail.
 | 
					 | 
				
			||||||
func (worker *Worker) broadcast(outpack *outPack) {
 | 
					func (worker *Worker) broadcast(outpack *outPack) {
 | 
				
			||||||
	for _, v := range worker.agents {
 | 
						for _, v := range worker.agents {
 | 
				
			||||||
		v.write(outpack)
 | 
							v.write(outpack)
 | 
				
			||||||
@ -88,8 +78,7 @@ func (worker *Worker) broadcast(outpack *outPack) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add a function.
 | 
					// Add a function.
 | 
				
			||||||
// Plz added job servers first, then functions.
 | 
					// Set timeout as Unlimited(=0) to disable executing timeout.
 | 
				
			||||||
// 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.Lock()
 | 
						worker.Lock()
 | 
				
			||||||
@ -104,7 +93,7 @@ func (worker *Worker) AddFunc(funcname string,
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// inner add function
 | 
					// inner add
 | 
				
			||||||
func (worker *Worker) addFunc(funcname string, timeout uint32) {
 | 
					func (worker *Worker) addFunc(funcname string, timeout uint32) {
 | 
				
			||||||
	outpack := getOutPack()
 | 
						outpack := getOutPack()
 | 
				
			||||||
	if timeout == 0 {
 | 
						if timeout == 0 {
 | 
				
			||||||
@ -135,7 +124,7 @@ func (worker *Worker) RemoveFunc(funcname string) (err error) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// inner remove function
 | 
					// inner remove
 | 
				
			||||||
func (worker *Worker) removeFunc(funcname string) {
 | 
					func (worker *Worker) removeFunc(funcname string) {
 | 
				
			||||||
	outpack := getOutPack()
 | 
						outpack := getOutPack()
 | 
				
			||||||
	outpack.dataType = CANT_DO
 | 
						outpack.dataType = CANT_DO
 | 
				
			||||||
@ -143,6 +132,7 @@ func (worker *Worker) removeFunc(funcname string) {
 | 
				
			|||||||
	worker.broadcast(outpack)
 | 
						worker.broadcast(outpack)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// inner package handling
 | 
				
			||||||
func (worker *Worker) handleInPack(inpack *inPack) {
 | 
					func (worker *Worker) handleInPack(inpack *inPack) {
 | 
				
			||||||
	switch inpack.dataType {
 | 
						switch inpack.dataType {
 | 
				
			||||||
	case NO_JOB:
 | 
						case NO_JOB:
 | 
				
			||||||
@ -168,6 +158,8 @@ func (worker *Worker) handleInPack(inpack *inPack) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Connect to Gearman server and tell every server
 | 
				
			||||||
 | 
					// what can this worker do.
 | 
				
			||||||
func (worker *Worker) Ready() (err error) {
 | 
					func (worker *Worker) Ready() (err error) {
 | 
				
			||||||
	for _, v := range worker.agents {
 | 
						for _, v := range worker.agents {
 | 
				
			||||||
		if err = v.Connect(); err != nil {
 | 
							if err = v.Connect(); err != nil {
 | 
				
			||||||
@ -180,11 +172,17 @@ func (worker *Worker) Ready() (err error) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Main loop
 | 
					// Main loop, block here
 | 
				
			||||||
 | 
					// Most of time, this should be evaluated in goroutine.
 | 
				
			||||||
func (worker *Worker) Work() {
 | 
					func (worker *Worker) Work() {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							for _, a := range worker.agents {
 | 
				
			||||||
 | 
								a.Close()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
	worker.running = true
 | 
						worker.running = true
 | 
				
			||||||
	for _, v := range worker.agents {
 | 
						for _, a := range worker.agents {
 | 
				
			||||||
		v.Grab()
 | 
							a.Grab()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var inpack *inPack
 | 
						var inpack *inPack
 | 
				
			||||||
	for inpack = range worker.in {
 | 
						for inpack = range worker.in {
 | 
				
			||||||
@ -192,7 +190,7 @@ func (worker *Worker) Work() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// job handler
 | 
					// custome handling warper
 | 
				
			||||||
func (worker *Worker) customeHandler(inpack *inPack) {
 | 
					func (worker *Worker) customeHandler(inpack *inPack) {
 | 
				
			||||||
	if worker.JobHandler != nil {
 | 
						if worker.JobHandler != nil {
 | 
				
			||||||
		if err := worker.JobHandler(inpack); err != nil {
 | 
							if err := worker.JobHandler(inpack); err != nil {
 | 
				
			||||||
@ -201,13 +199,13 @@ func (worker *Worker) customeHandler(inpack *inPack) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close.
 | 
					// Close connection and exit main loop
 | 
				
			||||||
func (worker *Worker) Close() {
 | 
					func (worker *Worker) Close() {
 | 
				
			||||||
	worker.running = false
 | 
						worker.running = false
 | 
				
			||||||
	close(worker.in)
 | 
						close(worker.in)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Send a something out, get the samething back.
 | 
					// Echo
 | 
				
			||||||
func (worker *Worker) Echo(data []byte) {
 | 
					func (worker *Worker) Echo(data []byte) {
 | 
				
			||||||
	outpack := getOutPack()
 | 
						outpack := getOutPack()
 | 
				
			||||||
	outpack.dataType = ECHO_REQ
 | 
						outpack.dataType = ECHO_REQ
 | 
				
			||||||
@ -216,7 +214,7 @@ func (worker *Worker) Echo(data []byte) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Remove all of functions.
 | 
					// Remove all of functions.
 | 
				
			||||||
// Both from the worker or job servers.
 | 
					// Both from the worker and job servers.
 | 
				
			||||||
func (worker *Worker) Reset() {
 | 
					func (worker *Worker) Reset() {
 | 
				
			||||||
	outpack := getOutPack()
 | 
						outpack := getOutPack()
 | 
				
			||||||
	outpack.dataType = RESET_ABILITIES
 | 
						outpack.dataType = RESET_ABILITIES
 | 
				
			||||||
@ -233,7 +231,7 @@ func (worker *Worker) SetId(id string) {
 | 
				
			|||||||
	worker.broadcast(outpack)
 | 
						worker.broadcast(outpack)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Execute the job. And send back the result.
 | 
					// inner job executing
 | 
				
			||||||
func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
					func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if worker.limit != nil {
 | 
							if worker.limit != nil {
 | 
				
			||||||
@ -277,11 +275,13 @@ func (worker *Worker) exec(inpack *inPack) (err error) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// inner result
 | 
				
			||||||
type result struct {
 | 
					type result struct {
 | 
				
			||||||
	data []byte
 | 
						data []byte
 | 
				
			||||||
	err  error
 | 
						err  error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// executing timer
 | 
				
			||||||
func execTimeout(f JobFunc, job Job, timeout time.Duration) (r *result) {
 | 
					func execTimeout(f JobFunc, job Job, timeout time.Duration) (r *result) {
 | 
				
			||||||
	rslt := make(chan *result)
 | 
						rslt := make(chan *result)
 | 
				
			||||||
	defer close(rslt)
 | 
						defer close(rslt)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user