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
|
||||||
@ -39,14 +25,19 @@ type Worker struct {
|
|||||||
in chan *inPack
|
in chan *inPack
|
||||||
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