Could not trust os.EOF as the end of msg's mark.

This commit is contained in:
mikespook 2011-05-24 12:21:49 +08:00
parent 7eb966bc36
commit 82f0ab2cd5
4 changed files with 77 additions and 35 deletions

View File

@ -1,13 +1,21 @@
#!/usr/bin/python #!/usr/bin/python
from gearman import libgearman import gearman
def check_request_status(job_request):
if job_request.complete:
print "Job %s finished! Result: %s - %s" % (job_request.job.unique, job_request.state, job_request.result)
elif job_request.timed_out:
print "Job %s timed out!" % job_request.unique
elif job_request.state == JOB_UNKNOWN:
print "Job %s connection failed!" % job_request.unique
def main(): def main():
client = libgearman.Client() client = gearman.GearmanClient(['localhost:4730', 'otherhost:4730'])
client.add_server("127.0.0.1", 4730) completed_job_request = client.submit_job("ToUpper", "arbitrary binary data")
r = client.do("ToUpper", "arbitrary binary data") check_request_status(completed_job_request)
print r
if __name__ == '__main__': if __name__ == '__main__':
main() for i in range(100):
main()

View File

@ -1,20 +1,18 @@
#!/usr/bin/python #!/usr/bin/python
import time import time
from gearman import libgearman import gearman
def toUpper(job): def toUpper(worker, job):
r = job.get_workload().upper() r = job.data.upper()
print r print r
return r return r
def main(): def main():
worker = libgearman.Worker() worker = gearman.GearmanWorker(['localhost:4730'])
worker.add_server("127.0.0.1", 4730) worker.register_task('ToUpper', toUpper)
worker.add_function("ToUpper", toUpper) worker.work()
while True:
worker.work()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -73,11 +73,12 @@ func (client *Client) read() (data []byte, err os.Error) {
} }
// split package // split package
start, end := 0, 4 start, end := 0, 4
for i := 0; i < len(data); i ++{ tl := len(data)
for i := 0; i < tl; i ++{
if string(data[start:end]) == RES_STR { if string(data[start:end]) == RES_STR {
l := int(byteToUint32([4]byte{data[start+8], data[start+9], data[start+10], data[start+11]})) l := int(byteToUint32([4]byte{data[start+8], data[start+9], data[start+10], data[start+11]}))
total := l + 12 total := l + 12
if total == len(data) { if total == tl {
return return
} else { } else {
client.incoming <- data[total:] client.incoming <- data[total:]

View File

@ -15,6 +15,7 @@ type jobClient struct {
conn net.Conn conn net.Conn
worker *Worker worker *Worker
running bool running bool
incoming chan []byte
} }
// Create the client of job server. // Create the client of job server.
@ -23,33 +24,66 @@ func newJobClient(addr string, worker *Worker) (jobclient *jobClient, err os.Err
if err != nil { if err != nil {
return nil, err return nil, err
} }
jobclient = &jobClient{conn:conn, worker:worker, running:true} jobclient = &jobClient{conn:conn, worker:worker, running:true, incoming: make(chan []byte, QUEUE_CAP)}
return jobclient, err return jobclient, err
} }
// Internal read
func (client *jobClient) read() (data []byte, err os.Error){
if len(client.incoming) > 0 {
// incoming queue is not empty
data = <-client.incoming
} else {
for {
buf := make([]byte, BUFFER_SIZE)
var n int
if n, err = client.conn.Read(buf); err != nil {
if err == os.EOF && n == 0 {
err = nil
return
}
return
}
data = append(data, buf[0: n] ...)
if n < BUFFER_SIZE {
break
}
}
}
// split package
start := 0
tl := len(data)
for i := 0; i < tl; i ++{
if string(data[start:start+4]) == RES_STR {
l := int(byteToUint32([4]byte{data[start+8], data[start+9], data[start+10], data[start+11]}))
total := l + 12
if total == tl {
return
} else {
client.incoming <- data[total:]
data = data[:total]
return
}
} else {
start++
}
}
err = os.NewError("Invalid data struct.")
return
}
// Main loop. // Main loop.
func (client *jobClient) Work() { func (client *jobClient) Work() {
noop := true noop := true
OUT: for client.running { for client.running {
// grab job // got noop msg and incoming queue is zero, grab job
if noop { if noop && len(client.incoming) == 0 {
client.WriteJob(NewWorkerJob(REQ, GRAB_JOB, nil)) client.WriteJob(NewWorkerJob(REQ, GRAB_JOB, nil))
} }
var rel []byte rel, err := client.read()
for { if err != nil {
buf := make([]byte, BUFFER_SIZE) client.worker.ErrQueue <- err
n, err := client.conn.Read(buf) continue
if err != nil {
if err == os.EOF && n == 0 {
break
}
client.worker.ErrQueue <- err
continue OUT
}
rel = append(rel, buf[0: n] ...)
if n < BUFFER_SIZE {
break
}
} }
job, err := DecodeWorkerJob(rel) job, err := DecodeWorkerJob(rel)
if err != nil { if err != nil {
@ -91,6 +125,7 @@ func (client *jobClient) Write(buf []byte) (err os.Error) {
// Close. // Close.
func (client *jobClient) Close() (err os.Error) { func (client *jobClient) Close() (err os.Error) {
client.running = false client.running = false
close(client.incoming)
err = client.conn.Close() err = client.conn.Close()
return return
} }