processed ERROR package
This commit is contained in:
parent
4997e30a77
commit
358c8c4af0
13
README.md
13
README.md
@ -38,7 +38,7 @@ Usage
|
|||||||
|
|
||||||
## Client
|
## Client
|
||||||
|
|
||||||
c, err := client.New("127.0.0.1:4730")
|
c, err := client.New("tcp4", "127.0.0.1:4730")
|
||||||
// ...
|
// ...
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
data := []byte("Hello\x00 world")
|
data := []byte("Hello\x00 world")
|
||||||
@ -52,6 +52,17 @@ Usage
|
|||||||
handle := c.Do("ToUpper", data, client.JOB_NORMAL, jobHandler)
|
handle := c.Do("ToUpper", data, client.JOB_NORMAL, jobHandler)
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
Branches
|
||||||
|
========
|
||||||
|
|
||||||
|
Version 0.x means: _It is far far away from stable._
|
||||||
|
|
||||||
|
__Use at your own risk!__
|
||||||
|
|
||||||
|
* 0.1-testing Old API and some known issues, eg. [issue-14](https://github.com/mikespook/gearman-go/issues/14)
|
||||||
|
* 0.2-dev Refactoring a lot of things
|
||||||
|
* master current usable version
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mikespook/golib/idgen"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"github.com/mikespook/golib/idgen"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -21,15 +21,15 @@ handle := c.Do("foobar", []byte("data here"), JOB_LOW | JOB_BG)
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
type Client struct {
|
type Client struct {
|
||||||
net, addr string
|
net, addr, lastcall string
|
||||||
respHandler map[string]ResponseHandler
|
respHandler map[string]ResponseHandler
|
||||||
innerHandler map[string]ResponseHandler
|
innerHandler map[string]ResponseHandler
|
||||||
in chan []byte
|
in chan []byte
|
||||||
isConn bool
|
isConn bool
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
ErrorHandler ErrorHandler
|
|
||||||
|
|
||||||
|
ErrorHandler ErrorHandler
|
||||||
IdGen idgen.IdGen
|
IdGen idgen.IdGen
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +126,10 @@ func (client *Client) processLoop() {
|
|||||||
var err error
|
var err error
|
||||||
var data, leftdata []byte
|
var data, leftdata []byte
|
||||||
for data = range client.in {
|
for data = range client.in {
|
||||||
l = len(data)
|
|
||||||
if len(leftdata) > 0 { // some data left for processing
|
if len(leftdata) > 0 { // some data left for processing
|
||||||
data = append(leftdata, data...)
|
data = append(leftdata, data...)
|
||||||
}
|
}
|
||||||
|
l = len(data)
|
||||||
if l < MIN_PACKET_LEN { // not enough data
|
if l < MIN_PACKET_LEN { // not enough data
|
||||||
leftdata = data
|
leftdata = data
|
||||||
continue
|
continue
|
||||||
@ -138,13 +138,21 @@ func (client *Client) processLoop() {
|
|||||||
client.err(err)
|
client.err(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
leftdata = nil
|
||||||
switch resp.DataType {
|
switch resp.DataType {
|
||||||
|
case ERROR:
|
||||||
|
if client.lastcall != "" {
|
||||||
|
client.handleInner(client.lastcall, resp)
|
||||||
|
client.lastcall = ""
|
||||||
|
} else {
|
||||||
|
client.err(GetError(resp.Data))
|
||||||
|
}
|
||||||
case STATUS_RES:
|
case STATUS_RES:
|
||||||
client.handleInner("status-" + resp.Handle, resp)
|
client.handleInner("s"+resp.Handle, resp)
|
||||||
case JOB_CREATED:
|
case JOB_CREATED:
|
||||||
client.handleInner("created", resp)
|
client.handleInner("c", resp)
|
||||||
case ECHO_RES:
|
case ECHO_RES:
|
||||||
client.handleInner("echo", resp)
|
client.handleInner("e", resp)
|
||||||
case WORK_DATA, WORK_WARNING, WORK_STATUS, WORK_COMPLETE,
|
case WORK_DATA, WORK_WARNING, WORK_STATUS, WORK_COMPLETE,
|
||||||
WORK_FAIL, WORK_EXCEPTION:
|
WORK_FAIL, WORK_EXCEPTION:
|
||||||
client.handleResponse(resp.Handle, resp)
|
client.handleResponse(resp.Handle, resp)
|
||||||
@ -182,16 +190,22 @@ func (client *Client) handleInner(key string, resp *Response) {
|
|||||||
|
|
||||||
// Internal do
|
// Internal do
|
||||||
func (client *Client) do(funcname string, data []byte,
|
func (client *Client) do(funcname string, data []byte,
|
||||||
flag uint32) (handle string) {
|
flag uint32) (handle string, err error) {
|
||||||
id := client.IdGen.Id().(string)
|
id := client.IdGen.Id().(string)
|
||||||
req := getJob(funcname, id, data)
|
req := getJob(id, []byte(funcname), data)
|
||||||
|
req.DataType = flag
|
||||||
client.write(req)
|
client.write(req)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
client.mutex.RLock()
|
client.mutex.RLock()
|
||||||
client.innerHandler["created"] = ResponseHandler(func(resp *Response) {
|
client.lastcall = "c"
|
||||||
|
client.innerHandler["c"] = ResponseHandler(func(resp *Response) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
defer client.mutex.RUnlock()
|
defer client.mutex.RUnlock()
|
||||||
|
if resp.DataType == ERROR {
|
||||||
|
err = GetError(resp.Data)
|
||||||
|
return
|
||||||
|
}
|
||||||
handle = resp.Handle
|
handle = resp.Handle
|
||||||
})
|
})
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -205,7 +219,7 @@ func (client *Client) do(funcname string, data []byte,
|
|||||||
// data is encoding to byte array.
|
// data is encoding to byte array.
|
||||||
// flag set the job type, include running level: JOB_LOW, JOB_NORMAL, JOB_HIGH
|
// flag set the job type, include running level: JOB_LOW, JOB_NORMAL, JOB_HIGH
|
||||||
func (client *Client) Do(funcname string, data []byte,
|
func (client *Client) Do(funcname string, data []byte,
|
||||||
flag byte, h ResponseHandler) (handle string) {
|
flag byte, h ResponseHandler) (handle string, err error) {
|
||||||
var datatype uint32
|
var datatype uint32
|
||||||
switch flag {
|
switch flag {
|
||||||
case JOB_LOW:
|
case JOB_LOW:
|
||||||
@ -215,7 +229,7 @@ func (client *Client) Do(funcname string, data []byte,
|
|||||||
default:
|
default:
|
||||||
datatype = SUBMIT_JOB
|
datatype = SUBMIT_JOB
|
||||||
}
|
}
|
||||||
handle = client.do(funcname, data, datatype)
|
handle, err = client.do(funcname, data, datatype)
|
||||||
client.mutex.Lock()
|
client.mutex.Lock()
|
||||||
defer client.mutex.Unlock()
|
defer client.mutex.Unlock()
|
||||||
if h != nil {
|
if h != nil {
|
||||||
@ -229,7 +243,7 @@ func (client *Client) Do(funcname string, data []byte,
|
|||||||
// data is encoding to byte array.
|
// data is encoding to byte array.
|
||||||
// flag set the job type, include running level: JOB_LOW, JOB_NORMAL, JOB_HIGH
|
// flag set the job type, include running level: JOB_LOW, JOB_NORMAL, JOB_HIGH
|
||||||
func (client *Client) DoBg(funcname string, data []byte,
|
func (client *Client) DoBg(funcname string, data []byte,
|
||||||
flag byte) (handle string) {
|
flag byte) (handle string, err error) {
|
||||||
var datatype uint32
|
var datatype uint32
|
||||||
switch flag {
|
switch flag {
|
||||||
case JOB_LOW:
|
case JOB_LOW:
|
||||||
@ -239,13 +253,13 @@ func (client *Client) DoBg(funcname string, data []byte,
|
|||||||
default:
|
default:
|
||||||
datatype = SUBMIT_JOB_BG
|
datatype = SUBMIT_JOB_BG
|
||||||
}
|
}
|
||||||
handle = client.do(funcname, data, datatype)
|
handle, err = client.do(funcname, data, datatype)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get job status from job server.
|
// Get job status from job server.
|
||||||
// !!!Not fully tested.!!!
|
// !!!Not fully tested.!!!
|
||||||
func (client *Client) Status(handle string, h ResponseHandler) (status *Status, err error) {
|
func (client *Client) Status(handle string) (status *Status, err error) {
|
||||||
req := getRequest()
|
req := getRequest()
|
||||||
req.DataType = GET_STATUS
|
req.DataType = GET_STATUS
|
||||||
req.Data = []byte(handle)
|
req.Data = []byte(handle)
|
||||||
@ -253,7 +267,8 @@ func (client *Client) Status(handle string, h ResponseHandler) (status *Status,
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
client.mutex.Lock()
|
client.mutex.Lock()
|
||||||
client.innerHandler["status-" + handle] = ResponseHandler(func(resp *Response) {
|
client.lastcall = "s" + handle
|
||||||
|
client.innerHandler["s" + handle] = ResponseHandler(func(resp *Response) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
defer client.mutex.Unlock()
|
defer client.mutex.Unlock()
|
||||||
var err error
|
var err error
|
||||||
@ -275,7 +290,8 @@ func (client *Client) Echo(data []byte) (echo []byte, err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
client.mutex.Lock()
|
client.mutex.Lock()
|
||||||
client.innerHandler["echo"] = ResponseHandler(func(resp *Response) {
|
client.lastcall = "e"
|
||||||
|
client.innerHandler["e"] = ResponseHandler(func(resp *Response) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
defer client.mutex.Unlock()
|
defer client.mutex.Unlock()
|
||||||
echo = resp.Data
|
echo = resp.Data
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var client *Client
|
const (
|
||||||
|
TestStr = "Hello world"
|
||||||
|
)
|
||||||
|
|
||||||
func printHandle(resp *Response) {
|
var client *Client
|
||||||
fmt.Printf("%V", resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClientAddServer(t *testing.T) {
|
func TestClientAddServer(t *testing.T) {
|
||||||
t.Log("Add local server 127.0.0.1:4730")
|
t.Log("Add local server 127.0.0.1:4730")
|
||||||
@ -24,17 +23,23 @@ func TestClientAddServer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClientEcho(t *testing.T) {
|
func TestClientEcho(t *testing.T) {
|
||||||
err := client.Echo([]byte("Hello world"), printHandle)
|
echo, err := client.Echo([]byte(TestStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if string(echo) != TestStr {
|
||||||
|
t.Errorf("Echo error, %s expected, %s got", TestStr, echo)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientDoBg(t *testing.T) {
|
func TestClientDoBg(t *testing.T) {
|
||||||
if handle := client.DoBg("ToUpper", []byte("abcdef"),
|
if handle := client.DoBg("ToUpper", []byte("abcdef"),
|
||||||
JOB_LOW); handle == "" {
|
JOB_LOW); handle == "" {
|
||||||
t.Error("Handle is empty.")
|
t.Error("Handle is empty.")
|
||||||
|
} else {
|
||||||
|
t.Log(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,38 +62,34 @@ func TestClientDo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClientStatus(t *testing.T) {
|
func TestClientStatus(t *testing.T) {
|
||||||
|
status, err := client.Status("handle not exists")
|
||||||
err := client.Status("handle not exists", printHandle)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*
|
if status.Known {
|
||||||
if s1.Known {
|
t.Errorf("The job (%s) shouldn't be known.", status.Handle)
|
||||||
t.Errorf("The job (%s) shouldn't be known.", s1.Handle)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s1.Running {
|
if status.Running {
|
||||||
t.Errorf("The job (%s) shouldn't be running.", s1.Handle)
|
t.Errorf("The job (%s) shouldn't be running.", status.Handle)
|
||||||
return
|
return
|
||||||
}*/
|
}
|
||||||
|
|
||||||
handle := client.Do("Delay5sec", []byte("abcdef"), JOB_LOW, nil)
|
handle := client.Do("Delay5sec", []byte("abcdef"), JOB_LOW, nil)
|
||||||
err = client.Status(handle, printHandle)
|
status, err = client.Status(handle)
|
||||||
/*
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !s2.Known {
|
if !status.Known {
|
||||||
t.Errorf("The job (%s) should be known.", s2.Handle)
|
t.Errorf("The job (%s) should be known.", status.Handle)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s2.Running {
|
if status.Running {
|
||||||
t.Errorf("The job (%s) shouldn't be running.", s2.Handle)
|
t.Errorf("The job (%s) shouldn't be running.", status.Handle)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientClose(t *testing.T) {
|
func TestClientClose(t *testing.T) {
|
||||||
|
@ -6,11 +6,9 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -33,17 +31,12 @@ var (
|
|||||||
func DisablePanic() { recover() }
|
func DisablePanic() { recover() }
|
||||||
|
|
||||||
// Extract the error message
|
// Extract the error message
|
||||||
func GetError(data []byte) (eno syscall.Errno, err error) {
|
func GetError(data []byte) (err error) {
|
||||||
rel := bytes.SplitN(data, []byte{'\x00'}, 2)
|
rel := bytes.SplitN(data, []byte{'\x00'}, 2)
|
||||||
if len(rel) != 2 {
|
if len(rel) != 2 {
|
||||||
err = fmt.Errorf("Not a error data: %V", data)
|
err = fmt.Errorf("Not a error data: %V", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var n uint64
|
err = errors.New(fmt.Sprintf("%s: %s", rel[0], rel[1]))
|
||||||
if n, err = strconv.ParseUint(string(rel[0]), 10, 0); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
eno = syscall.Errno(n)
|
|
||||||
err = errors.New(string(rel[1]))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -94,26 +94,26 @@ func (pool *Pool) Remove(addr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pool *Pool) Do(funcname string, data []byte,
|
func (pool *Pool) Do(funcname string, data []byte,
|
||||||
flag byte, h ResponseHandler) (addr, handle string) {
|
flag byte, h ResponseHandler) (addr, handle string, err error) {
|
||||||
client := pool.selectServer()
|
client := pool.selectServer()
|
||||||
handle = client.Do(funcname, data, flag, h)
|
handle, err = client.Do(funcname, data, flag, h)
|
||||||
addr = client.addr
|
addr = client.addr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *Pool) DoBg(funcname string, data []byte,
|
func (pool *Pool) DoBg(funcname string, data []byte,
|
||||||
flag byte) (addr, handle string) {
|
flag byte) (addr, handle string, err error) {
|
||||||
client := pool.selectServer()
|
client := pool.selectServer()
|
||||||
handle = client.DoBg(funcname, data, flag)
|
handle, err = client.DoBg(funcname, data, flag)
|
||||||
addr = client.addr
|
addr = client.addr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get job status from job server.
|
// Get job status from job server.
|
||||||
// !!!Not fully tested.!!!
|
// !!!Not fully tested.!!!
|
||||||
func (pool *Pool) Status(addr, handle string, h ResponseHandler) (status *Status, err error) {
|
func (pool *Pool) Status(addr, handle string) (status *Status, err error) {
|
||||||
if client, ok := pool.clients[addr]; ok {
|
if client, ok := pool.clients[addr]; ok {
|
||||||
status, err = client.Status(handle, h)
|
status, err = client.Status(handle)
|
||||||
} else {
|
} else {
|
||||||
err = ErrNotFound
|
err = ErrNotFound
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ func (pool *Pool) Status(addr, handle string, h ResponseHandler) (status *Status
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send a something out, get the samething back.
|
// Send a something out, get the samething back.
|
||||||
func (pool *Pool) Echo(addr string, data []byte, h ResponseHandler) (echo []byte, err error) {
|
func (pool *Pool) Echo(addr string, data []byte) (echo []byte, err error) {
|
||||||
var client *poolClient
|
var client *poolClient
|
||||||
if addr == "" {
|
if addr == "" {
|
||||||
client = pool.selectServer()
|
client = pool.selectServer()
|
||||||
|
@ -13,7 +13,7 @@ func TestPoolAdd(t *testing.T) {
|
|||||||
if err := pool.Add("tcp4", "127.0.0.1:4730", 1); err != nil {
|
if err := pool.Add("tcp4", "127.0.0.1:4730", 1); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if err := pool.Add("tcp4", "127.0.0.1:4730", 1); err != nil {
|
if err := pool.Add("tcp4", "127.0.1.1:4730", 1); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if len(pool.clients) != 2 {
|
if len(pool.clients) != 2 {
|
||||||
@ -22,17 +22,17 @@ func TestPoolAdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPoolEcho(t *testing.T) {
|
func TestPoolEcho(t *testing.T) {
|
||||||
echo, err := pool.Echo("", []byte("Hello pool"), printHandle)
|
echo, err := pool.Echo("", []byte(TestStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if string(echo) != "Hello pool" {
|
if string(echo) != TestStr {
|
||||||
t.Errorf("Invalid echo data: %s", echo)
|
t.Errorf("Invalid echo data: %s", echo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = pool.Echo("not exists", []byte("Hello pool"), printHandle)
|
_, err = pool.Echo("not exists", []byte(TestStr))
|
||||||
if err != ErrNotFound {
|
if err != ErrNotFound {
|
||||||
t.Errorf("ErrNotFound expected, got %s", err)
|
t.Errorf("ErrNotFound expected, got %s", err)
|
||||||
}
|
}
|
||||||
@ -66,36 +66,34 @@ func TestPoolDo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPoolStatus(t *testing.T) {
|
func TestPoolStatus(t *testing.T) {
|
||||||
err := pool.Status("127.0.0.1:4730", "handle not exists", printHandle)
|
status, err := pool.Status("127.0.0.1:4730", "handle not exists")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*
|
if status.Known {
|
||||||
if s1.Known {
|
t.Errorf("The job (%s) shouldn't be known.", status.Handle)
|
||||||
t.Errorf("The job (%s) shouldn't be known.", s1.Handle)
|
|
||||||
}
|
}
|
||||||
if s1.Running {
|
if status.Running {
|
||||||
t.Errorf("The job (%s) shouldn't be running.", s1.Handle)
|
t.Errorf("The job (%s) shouldn't be running.", status.Handle)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
addr, handle := pool.Do("Delay5sec", []byte("abcdef"), JOB_LOW, nil)
|
addr, handle := pool.Do("Delay5sec", []byte("abcdef"), JOB_LOW, nil)
|
||||||
err = pool.Status(addr, handle, printHandle)
|
status, err = pool.Status(addr, handle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if !s2.Known {
|
if !status.Known {
|
||||||
t.Errorf("The job (%s) should be known.", s2.Handle)
|
t.Errorf("The job (%s) should be known.", status.Handle)
|
||||||
}
|
}
|
||||||
if s2.Running {
|
if status.Running {
|
||||||
t.Errorf("The job (%s) shouldn't be running.", s2.Handle)
|
t.Errorf("The job (%s) shouldn't be running.", status.Handle)
|
||||||
}
|
}
|
||||||
*/
|
status, err = pool.Status("not exists", "not exists")
|
||||||
err = pool.Status("not exists", "not exists", printHandle)
|
|
||||||
if err != ErrNotFound {
|
if err != ErrNotFound {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func getRequest() (req *request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getJob(funcname, id string, data []byte) (req *request) {
|
func getJob(id string, funcname, data []byte) (req *request) {
|
||||||
req = getRequest()
|
req = getRequest()
|
||||||
a := len(funcname)
|
a := len(funcname)
|
||||||
b := len(id)
|
b := len(id)
|
||||||
|
@ -6,17 +6,17 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"encoding/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
// response
|
// response
|
||||||
type Response struct {
|
type Response struct {
|
||||||
DataType uint32
|
DataType uint32
|
||||||
Data []byte
|
Data, UID []byte
|
||||||
UID, Handle string
|
Handle string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the Response's result.
|
// Extract the Response's result.
|
||||||
@ -82,9 +82,9 @@ func decodeResponse(data []byte) (resp *Response, l int, err error) {
|
|||||||
resp = getResponse()
|
resp = getResponse()
|
||||||
resp.DataType = binary.BigEndian.Uint32(data[4:8])
|
resp.DataType = binary.BigEndian.Uint32(data[4:8])
|
||||||
switch resp.DataType {
|
switch resp.DataType {
|
||||||
case ECHO_RES:
|
case JOB_CREATED:
|
||||||
resp.Data = dt
|
resp.Handle = string(dt)
|
||||||
case WORK_DATA, WORK_WARNING, WORK_STATUS,
|
case STATUS_RES, WORK_DATA, WORK_WARNING, WORK_STATUS,
|
||||||
WORK_COMPLETE, WORK_FAIL, WORK_EXCEPTION:
|
WORK_COMPLETE, WORK_FAIL, WORK_EXCEPTION:
|
||||||
s := bytes.SplitN(dt, []byte{'\x00'}, 2)
|
s := bytes.SplitN(dt, []byte{'\x00'}, 2)
|
||||||
if len(s) >= 2 {
|
if len(s) >= 2 {
|
||||||
@ -94,8 +94,12 @@ func decodeResponse(data []byte) (resp *Response, l int, err error) {
|
|||||||
err = fmt.Errorf("Invalid data: %V", data)
|
err = fmt.Errorf("Invalid data: %V", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case ECHO_RES:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
resp.Data = dt
|
||||||
}
|
}
|
||||||
l = len(resp.Data) + MIN_PACKET_LEN
|
l = dl + MIN_PACKET_LEN
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,23 +113,23 @@ func (resp *Response) IsStatus() bool {
|
|||||||
|
|
||||||
// status handler
|
// status handler
|
||||||
func (resp *Response) Status() (status *Status, err error) {
|
func (resp *Response) Status() (status *Status, err error) {
|
||||||
data := bytes.SplitN(resp.Data, []byte{'\x00'}, 5)
|
data := bytes.SplitN(resp.Data, []byte{'\x00'}, 4)
|
||||||
if len(data) != 5 {
|
if len(data) != 4 {
|
||||||
err = fmt.Errorf("Invalid data: %V", resp.Data)
|
err = fmt.Errorf("Invalid data: %V", resp.Data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
status = &Status{}
|
status = &Status{}
|
||||||
status.Handle = data[0]
|
status.Handle = resp.Handle
|
||||||
status.Known = (data[1][0] == '1')
|
status.Known = (data[0][0] == '1')
|
||||||
status.Running = (data[2][0] == '1')
|
status.Running = (data[1][0] == '1')
|
||||||
status.Numerator, err = strconv.ParseUint(string(data[3]), 10, 0)
|
status.Numerator, err = strconv.ParseUint(string(data[2]), 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Invalid Integer: %s", data[3])
|
err = fmt.Errorf("Invalid Integer: %s", data[2])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
status.Denominator, err = strconv.ParseUint(string(data[4]), 10, 0)
|
status.Denominator, err = strconv.ParseUint(string(data[3]), 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Invalid Integer: %s", data[4])
|
err = fmt.Errorf("Invalid Integer: %s", data[3])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
type Status struct {
|
type Status struct {
|
||||||
Handle []byte
|
Handle string
|
||||||
Known, Running bool
|
Known, Running bool
|
||||||
Numerator, Denominator uint64
|
Numerator, Denominator uint64
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ func TestJobs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer w.Close()
|
defer w.Close()
|
||||||
|
t.Log("Servers added...")
|
||||||
if err := w.AddFunc("ToUpper", ToUpper, 0); err != nil {
|
if err := w.AddFunc("ToUpper", ToUpper, 0); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@ -49,38 +50,42 @@ func TestJobs(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t.Log("Functions added...")
|
||||||
w.ErrHandler = func(e error) {
|
w.ErrHandler = func(e error) {
|
||||||
t.Error(e)
|
t.Error(e)
|
||||||
}
|
}
|
||||||
go w.Work()
|
go w.Work()
|
||||||
|
t.Log("Worker is running...")
|
||||||
|
|
||||||
c, err := client.New(GEARMAND)
|
c, err := client.New("tcp4", GEARMAND)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
c.ErrHandler = func(e error) {
|
c.ErrorHandler = func(e error) {
|
||||||
// t.Error(e)
|
|
||||||
t.Log(e)
|
t.Log(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var w sync.WaitGroup
|
var w sync.WaitGroup
|
||||||
jobHandler := func(job *client.Job) {
|
jobHandler := func(job *client.Response) {
|
||||||
upper := strings.ToUpper(STR)
|
upper := strings.ToUpper(STR)
|
||||||
if (string(job.Data) != upper) {
|
if (string(job.Data) != upper) {
|
||||||
t.Error("%s expected, got %s", []byte(upper), job.Data)
|
t.Errorf("%s expected, got %s", upper, job.Data)
|
||||||
}
|
}
|
||||||
w.Done()
|
w.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Add(1)
|
w.Add(1)
|
||||||
handle := c.Do("ToUpper", []byte(STR), client.JOB_NORMAL, jobHandler)
|
handle, err := c.Do("ToUpper", []byte(STR), client.JOB_NORMAL, jobHandler)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
w.Wait()
|
w.Wait()
|
||||||
status, err := c.Status(handle, time.Second)
|
status, err := c.Status(handle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@ -95,9 +100,13 @@ func TestJobs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
handle := c.DoBg("Sleep", nil, client.JOB_NORMAL)
|
handle, err := c.DoBg("Sleep", nil, client.JOB_NORMAL)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
status, err := c.Status(handle, time.Second)
|
status, err := c.Status(handle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@ -113,7 +122,7 @@ func TestJobs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
status, err := c.Status("not exists handle", time.Second)
|
status, err := c.Status("not exists handle")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user