a better doc

This commit is contained in:
Xing Xing 2013-12-25 18:11:01 +08:00
parent 02e6bfebcb
commit 298edadfa6
2 changed files with 41 additions and 41 deletions

View File

@ -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"
*/ */

View File

@ -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)