no eof got invalid package, would modify the depack method

This commit is contained in:
mikespook 2011-05-21 12:32:44 +08:00
parent 016dd669aa
commit d8882938f7
7 changed files with 57 additions and 38 deletions

View File

@ -10,13 +10,18 @@ func main() {
defer client.Close() defer client.Close()
client.AddServer("127.0.0.1:4730") client.AddServer("127.0.0.1:4730")
echo := []byte("Hello world") echo := []byte("Hello world")
/*
log.Println(echo) log.Println(echo)
log.Println(client.Echo(echo)) log.Println(client.Echo(echo))
*/
handle, err := client.Do("ToUpper", echo, gearman.JOB_HIGH) handle, err := client.Do("ToUpper", echo, gearman.JOB_NORMAL)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} else {
log.Println(handle)
log.Println(<-client.JobQueue)
} }
/*
known, running, numerator, denominator, err := client.Status(handle) known, running, numerator, denominator, err := client.Status(handle)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -37,4 +42,5 @@ func main() {
log.Println(err) log.Println(err)
log.Println(data) log.Println(data)
} }
*/
} }

View File

@ -28,7 +28,10 @@ func main() {
switch str { switch str {
case "echo": case "echo":
worker.Echo([]byte("Hello world!")) worker.Echo([]byte("Hello world!"))
job := <-worker.JobQueue var job *gearman.WorkerJob
for job = <-worker.JobQueue; job.DataType != gearman.ECHO_RES; job = <-worker.JobQueue {
log.Println(job)
}
log.Println(string(job.Data)) log.Println(string(job.Data))
case "quit": case "quit":
worker.Close() worker.Close()

View File

@ -4,17 +4,21 @@ import (
"os" "os"
"net" "net"
"sync" "sync"
"log"
"strconv"
) )
type Client struct { type Client struct {
mutex sync.Mutex mutex sync.Mutex
conn net.Conn conn net.Conn
JobQueue chan *ClientJob JobQueue chan *ClientJob
incoming chan []byte
UId uint32 UId uint32
} }
func NewClient() (client * Client){ func NewClient() (client * Client){
client = &Client{JobQueue:make(chan *ClientJob, QUEUE_CAP), client = &Client{JobQueue:make(chan *ClientJob, QUEUE_CAP),
incoming:make(chan []byte, QUEUE_CAP),
UId:1} UId:1}
return return
} }
@ -28,7 +32,7 @@ func (client *Client) AddServer(addr string) (err os.Error) {
return return
} }
func (client *Client) ReadJob() (job *ClientJob, err os.Error) { func (client *Client) read() (data []byte, err os.Error) {
var rel []byte var rel []byte
for { for {
buf := make([]byte, BUFFER_SIZE) buf := make([]byte, BUFFER_SIZE)
@ -44,10 +48,17 @@ func (client *Client) ReadJob() (job *ClientJob, err os.Error) {
break break
} }
} }
}
func (client *Client) ReadJob() (job *ClientJob, err os.Error) {
var rel []byte
if rel, err = client.read(); err != nil {
return
}
if job, err = DecodeClientJob(rel); err != nil { if job, err = DecodeClientJob(rel); err != nil {
return return
} else { } else {
switch(job.dataType) { switch(job.DataType) {
case ERROR: case ERROR:
_, err = getError(job.Data) _, err = getError(job.Data)
return return
@ -82,9 +93,9 @@ func (client *Client) Do(funcname string, data []byte, flag byte) (handle string
rel = append(rel, []byte(funcname) ...) rel = append(rel, []byte(funcname) ...)
rel = append(rel, '\x00') rel = append(rel, '\x00')
client.mutex.Lock() client.mutex.Lock()
uid := uint32ToByte(client.UId) uid := strconv.Itoa(int(client.UId))
client.UId ++ client.UId ++
rel = append(rel, uid[:] ...) rel = append(rel, []byte(uid) ...)
client.mutex.Unlock() client.mutex.Unlock()
rel = append(rel, '\x00') rel = append(rel, '\x00')
rel = append(rel, data ...) rel = append(rel, data ...)
@ -92,17 +103,18 @@ func (client *Client) Do(funcname string, data []byte, flag byte) (handle string
return return
} }
var job *ClientJob var job *ClientJob
if job, err = client.ReadLastJob(JOB_CREATED); err != nil { if job, err = client.readLastJob(JOB_CREATED); err != nil {
return return
} }
handle = string(job.Data) handle = string(job.Data)
log.Println(handle)
go func() { go func() {
if flag & JOB_BG != JOB_BG { if flag & JOB_BG != JOB_BG {
for { for {
if job, err = client.ReadJob(); err != nil { if job, err = client.ReadJob(); err != nil {
return return
} }
switch job.dataType { switch job.DataType {
case WORK_DATA, WORK_WARNING: case WORK_DATA, WORK_WARNING:
case WORK_STATUS: case WORK_STATUS:
case WORK_COMPLETE, WORK_FAIL, WORK_EXCEPTION: case WORK_COMPLETE, WORK_FAIL, WORK_EXCEPTION:
@ -114,16 +126,16 @@ func (client *Client) Do(funcname string, data []byte, flag byte) (handle string
return return
} }
func (client *Client) ReadLastJob(datatype uint32) (job *ClientJob, err os.Error){ func (client *Client) readLastJob(datatype uint32) (job *ClientJob, err os.Error){
for { for {
if job, err = client.ReadJob(); err != nil { if job, err = client.ReadJob(); err != nil {
return return
} }
if job.dataType == datatype { if job.DataType == datatype {
break break
} }
} }
if job.dataType != datatype { if job.DataType != datatype {
err = os.NewError("No job got.") err = os.NewError("No job got.")
} }
return return
@ -135,7 +147,7 @@ func (client *Client) Status(handle string) (known, running bool, numerator, den
return return
} }
var job * ClientJob var job * ClientJob
if job, err = client.ReadLastJob(STATUS_RES); err != nil { if job, err = client.readLastJob(STATUS_RES); err != nil {
return return
} }
data := splitByteArray(job.Data, '\x00') data := splitByteArray(job.Data, '\x00')
@ -159,7 +171,7 @@ func (client *Client) Echo(data []byte) (echo []byte, err os.Error) {
return return
} }
var job *ClientJob var job *ClientJob
if job, err = client.ReadLastJob(ECHO_RES); err != nil { if job, err = client.readLastJob(ECHO_RES); err != nil {
return return
} }
return job.Data, err return job.Data, err
@ -178,10 +190,10 @@ func (client *Client) LastResult() (job *ClientJob) {
} }
func (client *Client) WriteJob(job *ClientJob) (err os.Error) { func (client *Client) WriteJob(job *ClientJob) (err os.Error) {
return client.Write(job.Encode()) return client.write(job.Encode())
} }
func (client *Client) Write(buf []byte) (err os.Error) { func (client *Client) write(buf []byte) (err os.Error) {
var n int var n int
for i := 0; i < len(buf); i += n { for i := 0; i < len(buf); i += n {
n, err = client.conn.Write(buf[i:]) n, err = client.conn.Write(buf[i:])

View File

@ -7,14 +7,13 @@ import (
type ClientJob struct { type ClientJob struct {
Data []byte Data []byte
Handle string Handle, UniqueId string
UniqueId string magicCode, DataType uint32
magicCode, dataType uint32
} }
func NewClientJob(magiccode, datatype uint32, data []byte) (job *ClientJob) { func NewClientJob(magiccode, datatype uint32, data []byte) (job *ClientJob) {
return &ClientJob{magicCode:magiccode, return &ClientJob{magicCode:magiccode,
dataType:datatype, DataType:datatype,
Data:data} Data:data}
} }
@ -36,20 +35,19 @@ func DecodeClientJob(data []byte) (job * ClientJob, err os.Error) {
func (job *ClientJob) Encode() (data []byte) { func (job *ClientJob) Encode() (data []byte) {
magiccode := uint32ToByte(job.magicCode) magiccode := uint32ToByte(job.magicCode)
datatype := uint32ToByte(job.dataType) datatype := uint32ToByte(job.DataType)
data = make([]byte, 0, 1024 * 64) data = make([]byte, 0, 1024 * 64)
data = append(data, magiccode[:] ...) data = append(data, magiccode[:] ...)
data = append(data, datatype[:] ...) data = append(data, datatype[:] ...)
data = append(data, []byte{0, 0, 0, 0} ...)
l := len(job.Data) l := len(job.Data)
data = append(data, job.Data ...)
datalength := uint32ToByte(uint32(l)) datalength := uint32ToByte(uint32(l))
copy(data[8:12], datalength[:]) data = append(data, datalength[:] ...)
data = append(data, job.Data ...)
return return
} }
func (job * ClientJob) Result() (data []byte, err os.Error){ func (job * ClientJob) Result() (data []byte, err os.Error){
switch job.dataType { switch job.DataType {
case WORK_FAIL: case WORK_FAIL:
job.Handle = string(job.Data) job.Handle = string(job.Data)
err = os.NewError("Work fail.") err = os.NewError("Work fail.")
@ -72,7 +70,7 @@ func (job * ClientJob) Result() (data []byte, err os.Error){
} }
func (job *ClientJob) Update() (data []byte, err os.Error) { func (job *ClientJob) Update() (data []byte, err os.Error) {
if job.dataType != WORK_DATA && job.dataType != WORK_WARNING { if job.DataType != WORK_DATA && job.DataType != WORK_WARNING {
err = os.NewError("The job is not a update.") err = os.NewError("The job is not a update.")
return return
} }
@ -81,7 +79,7 @@ func (job *ClientJob) Update() (data []byte, err os.Error) {
err = os.NewError("Invalid data.") err = os.NewError("Invalid data.")
return return
} }
if job.dataType == WORK_WARNING { if job.DataType == WORK_WARNING {
err = os.NewError("Work warning") err = os.NewError("Work warning")
} }
job.Handle = string(s[0]) job.Handle = string(s[0])

View File

@ -111,7 +111,7 @@ func (worker * Worker) Work() {
if job == nil { if job == nil {
break break
} }
switch job.dataType { switch job.DataType {
case NO_JOB: case NO_JOB:
// do nothing // do nothing
case ERROR: case ERROR:
@ -120,8 +120,8 @@ func (worker * Worker) Work() {
case JOB_ASSIGN, JOB_ASSIGN_UNIQ: case JOB_ASSIGN, JOB_ASSIGN_UNIQ:
if err := worker.exec(job); err != nil { if err := worker.exec(job); err != nil {
worker.ErrQueue <- err worker.ErrQueue <- err
continue
} }
fallthrough
default: default:
worker.JobQueue <- job worker.JobQueue <- job
} }
@ -185,7 +185,7 @@ func (worker * Worker) exec(job *WorkerJob) (err os.Error) {
jobdata := splitByteArray(job.Data, '\x00') jobdata := splitByteArray(job.Data, '\x00')
job.Handle = string(jobdata[0]) job.Handle = string(jobdata[0])
funcname := string(jobdata[1]) funcname := string(jobdata[1])
if job.dataType == JOB_ASSIGN { if job.DataType == JOB_ASSIGN {
job.Data = jobdata[2] job.Data = jobdata[2]
} else { } else {
job.UniqueId = string(jobdata[2]) job.UniqueId = string(jobdata[2])
@ -208,7 +208,7 @@ func (worker * Worker) exec(job *WorkerJob) (err os.Error) {
} }
job.magicCode = REQ job.magicCode = REQ
job.dataType = datatype job.DataType = datatype
job.Data = result job.Data = result
worker.WriteJob(job) worker.WriteJob(job)

View File

@ -7,16 +7,15 @@ import (
type WorkerJob struct { type WorkerJob struct {
Data []byte Data []byte
Handle string Handle, UniqueId string
UniqueId string
client *jobClient client *jobClient
magicCode, dataType uint32 magicCode, DataType uint32
Job Job
} }
func NewWorkerJob(magiccode, datatype uint32, data []byte) (job *WorkerJob) { func NewWorkerJob(magiccode, datatype uint32, data []byte) (job *WorkerJob) {
return &WorkerJob{magicCode:magiccode, return &WorkerJob{magicCode:magiccode,
dataType: datatype, DataType: datatype,
Data:data} Data:data}
} }
@ -38,7 +37,7 @@ func DecodeWorkerJob(data []byte) (job *WorkerJob, err os.Error) {
func (job *WorkerJob) Encode() (data []byte) { func (job *WorkerJob) Encode() (data []byte) {
magiccode := uint32ToByte(job.magicCode) magiccode := uint32ToByte(job.magicCode)
datatype := uint32ToByte(job.dataType) datatype := uint32ToByte(job.DataType)
data = make([]byte, 0, 1024 * 64) data = make([]byte, 0, 1024 * 64)
data = append(data, magiccode[:] ...) data = append(data, magiccode[:] ...)
data = append(data, datatype[:] ...) data = append(data, datatype[:] ...)

View File

@ -3,7 +3,7 @@ package gearman
import ( import (
"net" "net"
"os" "os"
// "log" "log"
) )
type jobClient struct { type jobClient struct {
@ -44,12 +44,13 @@ func (client *jobClient) Work() {
break break
} }
} }
log.Println(string(rel))
job, err := DecodeWorkerJob(rel) job, err := DecodeWorkerJob(rel)
if err != nil { if err != nil {
client.worker.ErrQueue <- err client.worker.ErrQueue <- err
continue continue
} else { } else {
switch(job.dataType) { switch(job.DataType) {
case NOOP: case NOOP:
noop = true noop = true
case NO_JOB: case NO_JOB: