a better documents
This commit is contained in:
parent
298edadfa6
commit
18791d0490
@ -1,4 +1,7 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.2
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install -qq gearman-job-server
|
||||
- sudo apt-get remove -y gearman-job-server
|
||||
- sudo apt-get install -y gearman-job-server
|
||||
|
Binary file not shown.
@ -3,10 +3,12 @@ package worker
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// The agent of job server.
|
||||
type agent struct {
|
||||
sync.Mutex
|
||||
conn net.Conn
|
||||
worker *Worker
|
||||
in chan []byte
|
||||
@ -25,6 +27,8 @@ func newAgent(net, addr string, worker *Worker) (a *agent, err error) {
|
||||
}
|
||||
|
||||
func (a *agent) Connect() (err error) {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
a.conn, err = net.Dial(a.net, a.addr)
|
||||
if err != nil {
|
||||
return
|
||||
@ -40,11 +44,18 @@ func (a *agent) work() {
|
||||
var data, leftdata []byte
|
||||
for {
|
||||
if data, err = a.read(BUFFER_SIZE); err != nil {
|
||||
if err == ErrConnClosed {
|
||||
a.worker.err(err)
|
||||
if err == ErrLostConn {
|
||||
break
|
||||
}
|
||||
// If it is unexpected error and the connection wasn't
|
||||
// closed by Gearmand, the agent should colse the conection
|
||||
// and reconnect to job server.
|
||||
a.conn, err = net.Dial(a.net, a.addr)
|
||||
if err != nil {
|
||||
a.worker.err(err)
|
||||
break
|
||||
}
|
||||
a.worker.err(err)
|
||||
continue
|
||||
}
|
||||
if len(leftdata) > 0 { // some data left for processing
|
||||
data = append(leftdata, data...)
|
||||
@ -67,16 +78,25 @@ func (a *agent) work() {
|
||||
}
|
||||
|
||||
func (a *agent) Close() {
|
||||
a.conn.Close()
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
if a.conn != nil {
|
||||
a.conn.Close()
|
||||
a.conn = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *agent) Grab() {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
outpack := getOutPack()
|
||||
outpack.dataType = GRAB_JOB_UNIQ
|
||||
a.write(outpack)
|
||||
}
|
||||
|
||||
func (a *agent) PreSleep() {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
outpack := getOutPack()
|
||||
outpack.dataType = PRE_SLEEP
|
||||
a.write(outpack)
|
||||
@ -89,12 +109,8 @@ func (a *agent) read(length int) (data []byte, err error) {
|
||||
// read until data can be unpacked
|
||||
for i := length; i > 0 || len(data) < MIN_PACKET_LEN; i -= n {
|
||||
if n, err = a.conn.Read(buf); err != nil {
|
||||
if err == io.EOF && n == 0 {
|
||||
if data == nil {
|
||||
err = ErrConnection
|
||||
} else {
|
||||
err = ErrConnClosed
|
||||
}
|
||||
if err == io.EOF {
|
||||
err = ErrLostConn
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -7,20 +7,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrJobTimeOut = errors.New("Do a job time out")
|
||||
ErrInvalidData = errors.New("Invalid data")
|
||||
ErrWorkWarning = errors.New("Work warning")
|
||||
ErrWorkFail = errors.New("Work fail")
|
||||
ErrWorkException = errors.New("Work exeption")
|
||||
ErrDataType = errors.New("Invalid data type")
|
||||
ErrOutOfCap = errors.New("Out of the capability")
|
||||
ErrNotConn = errors.New("Did not connect to job server")
|
||||
ErrFuncNotFound = errors.New("The function was not found")
|
||||
ErrConnection = errors.New("Connection error")
|
||||
ErrNoActiveAgent = errors.New("No active agent")
|
||||
ErrTimeOut = errors.New("Executing time out")
|
||||
ErrUnknown = errors.New("Unknown error")
|
||||
ErrConnClosed = errors.New("Connection closed")
|
||||
ErrNoneAgents = errors.New("None active agents")
|
||||
ErrNoneFuncs = errors.New("None functions")
|
||||
ErrTimeOut = errors.New("Executing time out")
|
||||
ErrUnknown = errors.New("Unknown error")
|
||||
ErrLostConn = errors.New("Lost connection with Gearmand")
|
||||
)
|
||||
|
||||
// Extract the error message
|
||||
|
57
worker/example_test.go
Normal file
57
worker/example_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package worker_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mikespook/gearman-go/worker"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func ExampleWorker() {
|
||||
// An example of worker
|
||||
w := worker.New(worker.Unlimited)
|
||||
defer w.Close()
|
||||
// Add a gearman job server
|
||||
if err := w.AddServer("tcp4", "127.0.0.1:4730"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// A function for handling jobs
|
||||
foobar := func(job worker.Job) ([]byte, error) {
|
||||
// Do nothing here
|
||||
return nil, nil
|
||||
}
|
||||
// Add the function to worker
|
||||
if err := w.AddFunc("foobar", foobar, 0); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
// A custome handler, for handling other results, eg. ECHO, ERROR.
|
||||
w.JobHandler = func(job worker.Job) error {
|
||||
if job.Err() == nil {
|
||||
fmt.Println(string(job.Data()))
|
||||
} else {
|
||||
fmt.Println(job.Err())
|
||||
}
|
||||
wg.Done()
|
||||
return nil
|
||||
}
|
||||
// An error handler for handling worker's internal errors.
|
||||
w.ErrorHandler = func(e error) {
|
||||
fmt.Println(e)
|
||||
// Ignore the error or shutdown the worker
|
||||
}
|
||||
// Tell Gearman job server: I'm ready!
|
||||
if err := w.Ready(); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// Running main loop
|
||||
go w.Work()
|
||||
wg.Add(1)
|
||||
// calling Echo
|
||||
w.Echo([]byte("Hello"))
|
||||
// Waiting results
|
||||
wg.Wait()
|
||||
// Output: Hello
|
||||
}
|
@ -24,6 +24,13 @@ func (inpack *inPack) Data() []byte {
|
||||
return inpack.data
|
||||
}
|
||||
|
||||
func (inpack *inPack) Err() error {
|
||||
if inpack.dataType == ERROR {
|
||||
return GetError(inpack.data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Send some datas to client.
|
||||
// Using this in a job's executing.
|
||||
func (inpack *inPack) SendData(data []byte) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package worker
|
||||
|
||||
type Job interface {
|
||||
Err() error
|
||||
Data() []byte
|
||||
SendWarning(data []byte)
|
||||
SendData(data []byte)
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Unlimited = 0
|
||||
OneByOne = 1
|
||||
Unlimited = iota
|
||||
OneByOne
|
||||
|
||||
Immediately = 0
|
||||
Immediately = iota
|
||||
)
|
||||
|
||||
// Worker is the only structure needed by worker side developing.
|
||||
@ -139,8 +139,6 @@ func (worker *Worker) handleInPack(inpack *inPack) {
|
||||
inpack.a.PreSleep()
|
||||
case NOOP:
|
||||
inpack.a.Grab()
|
||||
case ERROR:
|
||||
worker.err(GetError(inpack.data))
|
||||
case JOB_ASSIGN, JOB_ASSIGN_UNIQ:
|
||||
go func() {
|
||||
if err := worker.exec(inpack); err != nil {
|
||||
@ -151,6 +149,9 @@ func (worker *Worker) handleInPack(inpack *inPack) {
|
||||
worker.limit <- true
|
||||
}
|
||||
inpack.a.Grab()
|
||||
case ERROR:
|
||||
worker.err(inpack.Err())
|
||||
fallthrough
|
||||
case ECHO_RES:
|
||||
fallthrough
|
||||
default:
|
||||
@ -161,6 +162,12 @@ 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) {
|
||||
if len(worker.agents) == 0 {
|
||||
return ErrNoneAgents
|
||||
}
|
||||
if len(worker.funcs) == 0 {
|
||||
return ErrNoneFuncs
|
||||
}
|
||||
for _, v := range worker.agents {
|
||||
if err = v.Connect(); err != nil {
|
||||
return
|
||||
@ -201,8 +208,12 @@ func (worker *Worker) customeHandler(inpack *inPack) {
|
||||
|
||||
// Close connection and exit main loop
|
||||
func (worker *Worker) Close() {
|
||||
worker.running = false
|
||||
close(worker.in)
|
||||
worker.Lock()
|
||||
worker.Unlock()
|
||||
if worker.running == true {
|
||||
worker.running = false
|
||||
close(worker.in)
|
||||
}
|
||||
}
|
||||
|
||||
// Echo
|
||||
|
@ -11,6 +11,13 @@ func init() {
|
||||
worker = New(Unlimited)
|
||||
}
|
||||
|
||||
func TestWorkerErrNoneAgents(t *testing.T) {
|
||||
err := worker.Ready()
|
||||
if err != ErrNoneAgents {
|
||||
t.Error("ErrNoneAgents expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkerAddServer(t *testing.T) {
|
||||
t.Log("Add local server 127.0.0.1:4730.")
|
||||
if err := worker.AddServer("tcp4", "127.0.0.1:4730"); err != nil {
|
||||
@ -23,6 +30,13 @@ func TestWorkerAddServer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkerErrNoneFuncs(t *testing.T) {
|
||||
err := worker.Ready()
|
||||
if err != ErrNoneFuncs {
|
||||
t.Error("ErrNoneFuncs expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func foobar(job Job) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user