fixed client:Job.Encode
--HG-- branch : 0.1
This commit is contained in:
parent
7614c2678a
commit
563af037cb
@ -6,9 +6,9 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net"
|
||||
"bytes"
|
||||
"strconv"
|
||||
"bitbucket.org/mikespook/golib/autoinc"
|
||||
"bitbucket.org/mikespook/gearman-go/common"
|
||||
@ -24,8 +24,8 @@ type StatusHandler func(string, bool, bool, uint64, uint64)
|
||||
The client side api for gearman
|
||||
|
||||
usage:
|
||||
c := client.New("tcp4", "127.0.0.1:4730")
|
||||
handle := c.Do("foobar", []byte("data here"), JOB_LOW | JOB_BG)
|
||||
c := client.New("tcp4", "127.0.0.1:4730")
|
||||
handle := c.Do("foobar", []byte("data here"), JOB_LOW | JOB_BG)
|
||||
|
||||
*/
|
||||
type Client struct {
|
||||
@ -43,9 +43,9 @@ type Client struct {
|
||||
// Create a new client.
|
||||
// Connect to "addr" through "network"
|
||||
// Eg.
|
||||
// client, err := client.New("tcp4", "127.0.0.1:4730")
|
||||
func New(network, addr string) (client *Client, err error) {
|
||||
conn, err := net.Dial(network, addr)
|
||||
// client, err := client.New("127.0.0.1:4730")
|
||||
func New(addr string) (client *Client, err error) {
|
||||
conn, err := net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -56,8 +56,8 @@ func New(network, addr string) (client *Client, err error) {
|
||||
conn: conn,
|
||||
ai: autoinc.New(0, 1),
|
||||
}
|
||||
go client.outLoop()
|
||||
go client.inLoop()
|
||||
go client.outLoop()
|
||||
return
|
||||
}
|
||||
|
||||
@ -66,7 +66,9 @@ func (client *Client) outLoop() {
|
||||
ok := true
|
||||
for ok {
|
||||
if job, ok := <-client.out; ok {
|
||||
client.write(job.Encode())
|
||||
if err := client.write(job.Encode()); err != nil {
|
||||
client.err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,14 +90,14 @@ func (client *Client) inLoop() {
|
||||
case common.ERROR:
|
||||
_, err := common.GetError(job.Data)
|
||||
client.err(err)
|
||||
case common.WORK_DATA, common.WORK_WARNING, common.WORK_STATUS,
|
||||
case common.WORK_DATA, common.WORK_WARNING, common.WORK_STATUS,
|
||||
common.WORK_COMPLETE, common.WORK_FAIL, common.WORK_EXCEPTION,
|
||||
common.ECHO_RES:
|
||||
client.handleJob(job)
|
||||
go client.handleJob(job)
|
||||
case common.JOB_CREATED:
|
||||
client.jobCreated <- job
|
||||
case common.STATUS_RES:
|
||||
client.handleStatus(job)
|
||||
go client.handleStatus(job)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,6 +114,10 @@ func (client *Client) read() (data []byte, err error) {
|
||||
var n int
|
||||
if n, err = client.conn.Read(buf); err != nil {
|
||||
if err == io.EOF && n == 0 {
|
||||
if data == nil {
|
||||
err = common.ErrEmptyReading
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
return
|
||||
@ -123,8 +129,8 @@ func (client *Client) read() (data []byte, err error) {
|
||||
}
|
||||
}
|
||||
// split package
|
||||
start, end := 0, 4
|
||||
tl := len(data)
|
||||
start, end := 0, 4
|
||||
for i := 0; i < tl; i++ {
|
||||
if string(data[start:end]) == common.RES_STR {
|
||||
l := int(common.BytesToUint32([4]byte{data[start+8], data[start+9], data[start+10], data[start+11]}))
|
||||
@ -193,19 +199,19 @@ func (client *Client) handleStatus(job *Job) {
|
||||
// JOB_LOW | JOB_BG means the job is running with low level in background.
|
||||
func (client *Client) Do(funcname string, data []byte, flag byte) (handle string, err error) {
|
||||
var datatype uint32
|
||||
if flag & common.JOB_LOW == common.JOB_LOW {
|
||||
if flag & common.JOB_BG == common.JOB_BG {
|
||||
if flag & JOB_LOW == JOB_LOW {
|
||||
if flag & JOB_BG == JOB_BG {
|
||||
datatype = common.SUBMIT_JOB_LOW_BG
|
||||
} else {
|
||||
datatype = common.SUBMIT_JOB_LOW
|
||||
}
|
||||
} else if flag & common.JOB_HIGH == common.JOB_HIGH {
|
||||
if flag & common.JOB_BG == common.JOB_BG {
|
||||
} else if flag & JOB_HIGH == JOB_HIGH {
|
||||
if flag & JOB_BG == JOB_BG {
|
||||
datatype = common.SUBMIT_JOB_HIGH_BG
|
||||
} else {
|
||||
datatype = common.SUBMIT_JOB_HIGH
|
||||
}
|
||||
} else if flag & common.JOB_BG == common.JOB_BG {
|
||||
} else if flag & JOB_BG == JOB_BG {
|
||||
datatype = common.SUBMIT_JOB_BG
|
||||
} else {
|
||||
datatype = common.SUBMIT_JOB
|
||||
@ -213,14 +219,13 @@ func (client *Client) Do(funcname string, data []byte, flag byte) (handle string
|
||||
|
||||
uid := strconv.Itoa(int(client.ai.Id()))
|
||||
l := len(funcname) + len(uid) + len(data) + 2
|
||||
rel := make([]byte, l)
|
||||
rel := make([]byte, 0, l)
|
||||
rel = append(rel, []byte(funcname)...) // len(funcname)
|
||||
rel = append(rel, '\x00') // 1 Byte
|
||||
rel = append(rel, []byte(uid)...) // len(uid)
|
||||
rel = append(rel, '\x00') // 1 Byte
|
||||
rel = append(rel, data...) // len(data)
|
||||
client.writeJob(newJob(common.REQ, datatype, rel))
|
||||
|
||||
// Waiting for JOB_CREATED
|
||||
job := <-client.jobCreated
|
||||
return string(job.Data), nil
|
||||
@ -259,5 +264,6 @@ func (client *Client) write(buf []byte) (err error) {
|
||||
func (client *Client) Close() (err error) {
|
||||
close(client.jobCreated)
|
||||
close(client.in)
|
||||
close(client.out)
|
||||
return client.conn.Close();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"bitbucket.org/mikespook/gearman-go/common"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -10,9 +9,12 @@ var client *Client
|
||||
func TestClientAddServer(t *testing.T) {
|
||||
t.Log("Add local server 127.0.0.1:4730")
|
||||
var err error
|
||||
if client, err = New("tcp4", "127.0.0.1:4730"); err != nil {
|
||||
if client, err = New("127.0.0.1:4730"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
client.ErrHandler = func(e error) {
|
||||
t.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientEcho(t *testing.T) {
|
||||
@ -29,7 +31,7 @@ func TestClientEcho(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClientDo(t *testing.T) {
|
||||
if handle, err := client.Do("ToUpper", []byte("abcdef"), common.JOB_LOW|common.JOB_BG); err != nil {
|
||||
if handle, err := client.Do("ToUpper", []byte("abcdef"), JOB_LOW|JOB_BG); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
t.Log(handle)
|
||||
|
@ -9,6 +9,20 @@ import (
|
||||
"bytes"
|
||||
"bitbucket.org/mikespook/gearman-go/common"
|
||||
)
|
||||
|
||||
const (
|
||||
// Job type
|
||||
// JOB_NORMAL | JOB_BG means a normal level job run in background
|
||||
// normal level
|
||||
JOB_NORMAL = 0
|
||||
// background job
|
||||
JOB_BG = 1
|
||||
// low level
|
||||
JOB_LOW = 2
|
||||
// high level
|
||||
JOB_HIGH = 4
|
||||
)
|
||||
|
||||
// An error handler
|
||||
type ErrorHandler func(error)
|
||||
|
||||
@ -42,13 +56,15 @@ func decodeJob(data []byte) (job *Job, err error) {
|
||||
|
||||
// Encode a job to byte slice
|
||||
func (job *Job) Encode() (data []byte) {
|
||||
l := len(job.Data) + 12
|
||||
data = make([]byte, l)
|
||||
l := len(job.Data)
|
||||
tl := l + 12
|
||||
data = make([]byte, tl)
|
||||
|
||||
magiccode := common.Uint32ToBytes(job.magicCode)
|
||||
datatype := common.Uint32ToBytes(job.DataType)
|
||||
datalength := common.Uint32ToBytes(uint32(l))
|
||||
for i := 0; i < l; i ++ {
|
||||
|
||||
for i := 0; i < tl; i ++ {
|
||||
switch {
|
||||
case i < 4:
|
||||
data[i] = magiccode[i]
|
||||
@ -60,6 +76,13 @@ func (job *Job) Encode() (data []byte) {
|
||||
data[i] = job.Data[i - 12]
|
||||
}
|
||||
}
|
||||
// Alternative
|
||||
/*
|
||||
data = append(data, magiccode[:] ...)
|
||||
data = append(data, datatype[:] ...)
|
||||
data = append(data, datalength[:] ...)
|
||||
data = append(data, job.Data ...)
|
||||
*/
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ var (
|
||||
ErrOutOfCap = errors.New("Out of the capability.")
|
||||
ErrNotConn = errors.New("Did not connect to job server.")
|
||||
ErrFuncNotFound = errors.New("The function was not found.")
|
||||
ErrEmptyReading = errors.New("Empty reading.")
|
||||
)
|
||||
|
||||
// Extract the error message
|
||||
|
@ -54,17 +54,6 @@ const (
|
||||
SUBMIT_JOB_HIGH_BG = 32
|
||||
SUBMIT_JOB_LOW = 33
|
||||
SUBMIT_JOB_LOW_BG = 34
|
||||
|
||||
// Job type
|
||||
// JOB_NORMAL | JOB_BG means a normal level job run in background
|
||||
// normal level
|
||||
JOB_NORMAL = 0
|
||||
// background job
|
||||
JOB_BG = 1
|
||||
// low level
|
||||
JOB_LOW = 2
|
||||
// high level
|
||||
JOB_HIGH = 4
|
||||
)
|
||||
|
||||
// Decode [4]byte to uint32
|
||||
|
@ -3,29 +3,32 @@ package main
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
"bitbucket.org/mikespook/gearman-go"
|
||||
"bitbucket.org/mikespook/gearman-go/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
c, err := client.New("tcp4", "127.0.0.1:4730")
|
||||
c, err := client.New("127.0.0.1:4730")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer c.Close()
|
||||
echo := []byte("Hello\x00 world")
|
||||
c.JobHandler = func(job *client.Job) error {
|
||||
log.Printf("%V", job)
|
||||
log.Printf("%s", job.Data)
|
||||
wg.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
c.ErrHandler = func(e error) {
|
||||
log.Println(e)
|
||||
panic(e)
|
||||
}
|
||||
wg.Add(1)
|
||||
c.Echo(echo)
|
||||
|
||||
handle, err := c.Do("ToUpper", echo, gearman.JOB_NORMAL)
|
||||
wg.Add(1)
|
||||
handle, err := c.Do("ToUpper", echo, client.JOB_NORMAL)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
} else {
|
||||
@ -38,5 +41,6 @@ func main() {
|
||||
}
|
||||
wg.Add(1)
|
||||
c.Status(handle)
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user