A better read method
This commit is contained in:
		
							parent
							
								
									b72825d48a
								
							
						
					
					
						commit
						36ba74f0dc
					
				@ -16,6 +16,8 @@ const (
 | 
				
			|||||||
    QUEUE_SIZE = 8
 | 
					    QUEUE_SIZE = 8
 | 
				
			||||||
    // read buffer size
 | 
					    // read buffer size
 | 
				
			||||||
    BUFFER_SIZE = 1024
 | 
					    BUFFER_SIZE = 1024
 | 
				
			||||||
 | 
					    // min packet length
 | 
				
			||||||
 | 
					    PACKET_LEN = 12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // \x00REQ
 | 
					    // \x00REQ
 | 
				
			||||||
    REQ     = 5391697
 | 
					    REQ     = 5391697
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										118
									
								
								worker/agent.go
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								worker/agent.go
									
									
									
									
									
								
							@ -5,18 +5,18 @@
 | 
				
			|||||||
package worker
 | 
					package worker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
					    "github.com/miraclesu/gearman-go/common"
 | 
				
			||||||
    "io"
 | 
					    "io"
 | 
				
			||||||
    "net"
 | 
					    "net"
 | 
				
			||||||
    "github.com/mikespook/gearman-go/common"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The agent of job server.
 | 
					// The agent of job server.
 | 
				
			||||||
type agent struct {
 | 
					type agent struct {
 | 
				
			||||||
    conn        net.Conn
 | 
					    conn   net.Conn
 | 
				
			||||||
    worker      *Worker
 | 
					    worker *Worker
 | 
				
			||||||
    in chan     []byte
 | 
					    in     chan []byte
 | 
				
			||||||
    out chan    *Job
 | 
					    out    chan *Job
 | 
				
			||||||
    addr string
 | 
					    addr   string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create the agent of job server.
 | 
					// Create the agent of job server.
 | 
				
			||||||
@ -26,11 +26,11 @@ func newAgent(addr string, worker *Worker) (a *agent, err error) {
 | 
				
			|||||||
        return
 | 
					        return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    a = &agent{
 | 
					    a = &agent{
 | 
				
			||||||
        conn: conn,
 | 
					        conn:   conn,
 | 
				
			||||||
        worker: worker,
 | 
					        worker: worker,
 | 
				
			||||||
        addr: addr,
 | 
					        addr:   addr,
 | 
				
			||||||
        in: make(chan []byte, common.QUEUE_SIZE),
 | 
					        in:     make(chan []byte, common.QUEUE_SIZE),
 | 
				
			||||||
        out: make(chan *Job, common.QUEUE_SIZE),
 | 
					        out:    make(chan *Job, common.QUEUE_SIZE),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // reset abilities
 | 
					    // reset abilities
 | 
				
			||||||
    a.WriteJob(newJob(common.REQ, common.RESET_ABILITIES, nil))
 | 
					    a.WriteJob(newJob(common.REQ, common.RESET_ABILITIES, nil))
 | 
				
			||||||
@ -62,12 +62,12 @@ func (a *agent) inLoop() {
 | 
				
			|||||||
    }()
 | 
					    }()
 | 
				
			||||||
    for a.worker.running {
 | 
					    for a.worker.running {
 | 
				
			||||||
        a.WriteJob(newJob(common.REQ, common.PRE_SLEEP, nil))
 | 
					        a.WriteJob(newJob(common.REQ, common.PRE_SLEEP, nil))
 | 
				
			||||||
        RESTART:
 | 
					    RESTART:
 | 
				
			||||||
        // got noop msg and in queue is zero, grab job
 | 
					        // got noop msg and in queue is zero, grab job
 | 
				
			||||||
        rel, err := a.read()
 | 
					        rel, err := a.read()
 | 
				
			||||||
        if err != nil {
 | 
					        if err != nil {
 | 
				
			||||||
            if err == common.ErrConnection {
 | 
					            if err == common.ErrConnection {
 | 
				
			||||||
                for i:= 0; i < 3 && a.worker.running; i++ {
 | 
					                for i := 0; i < 3 && a.worker.running; i++ {
 | 
				
			||||||
                    if conn, err := net.Dial(common.NETWORK, a.addr); err != nil {
 | 
					                    if conn, err := net.Dial(common.NETWORK, a.addr); err != nil {
 | 
				
			||||||
                        a.worker.err(common.Errorf("Reconnection: %d faild", i))
 | 
					                        a.worker.err(common.Errorf("Reconnection: %d faild", i))
 | 
				
			||||||
                        continue
 | 
					                        continue
 | 
				
			||||||
@ -106,64 +106,78 @@ func (a *agent) Work() {
 | 
				
			|||||||
    go a.inLoop()
 | 
					    go a.inLoop()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Internal read
 | 
					func (a *agent) readData(length int) (data []byte, err error) {
 | 
				
			||||||
func (a *agent) read() (data []byte, err error) {
 | 
					    n := 0
 | 
				
			||||||
BEGIN:
 | 
					    buf := make([]byte, common.BUFFER_SIZE)
 | 
				
			||||||
    inlen := len(a.in)
 | 
					    // read until data can be unpacked
 | 
				
			||||||
    if inlen > 0 {
 | 
					    for i := length; i > 0 || len(data) < common.PACKET_LEN; i -= n {
 | 
				
			||||||
        // in queue is not empty
 | 
					        if n, err = a.conn.Read(buf); err != nil {
 | 
				
			||||||
        for i := 0; i < inlen; i ++ {
 | 
					            if err == io.EOF && n == 0 {
 | 
				
			||||||
            data = append(data, <-a.in...)
 | 
					                if data == nil {
 | 
				
			||||||
        }
 | 
					                    err = common.ErrConnection
 | 
				
			||||||
    } else {
 | 
					                    return
 | 
				
			||||||
        for i := 0; i < 10; i ++ {
 | 
					 | 
				
			||||||
            buf := make([]byte, common.BUFFER_SIZE)
 | 
					 | 
				
			||||||
            var n int
 | 
					 | 
				
			||||||
            if n, err = a.conn.Read(buf); err != nil {
 | 
					 | 
				
			||||||
                if err == io.EOF && n == 0 {
 | 
					 | 
				
			||||||
                    if data == nil {
 | 
					 | 
				
			||||||
                        err = common.ErrConnection
 | 
					 | 
				
			||||||
                        return
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return
 | 
					                return data, nil
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            data = append(data, buf[0:n]...)
 | 
					 | 
				
			||||||
            if n < common.BUFFER_SIZE {
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        data = append(data, buf[0:n]...)
 | 
				
			||||||
 | 
					        if n < common.BUFFER_SIZE {
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // split package
 | 
					    return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *agent) unpack(data []byte) ([]byte, int, bool) {
 | 
				
			||||||
    tl := len(data)
 | 
					    tl := len(data)
 | 
				
			||||||
    if tl < 12 { // too few data to unpack, read more
 | 
					 | 
				
			||||||
        goto BEGIN
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    start := 0
 | 
					    start := 0
 | 
				
			||||||
    for i := 0; i < tl - 11; i++ {
 | 
					    for i := 0; i < tl+1-common.PACKET_LEN; i++ {
 | 
				
			||||||
        if start + 12 > tl { // too few data to unpack, read more
 | 
					        if start+common.PACKET_LEN > tl { // too few data to unpack, read more
 | 
				
			||||||
            goto BEGIN
 | 
					            return nil, common.PACKET_LEN, false
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if string(data[start:start+4]) == common.RES_STR {
 | 
					        if string(data[start:start+4]) == common.RES_STR {
 | 
				
			||||||
            l := int(common.BytesToUint32([4]byte{data[start+8],
 | 
					            l := int(common.BytesToUint32([4]byte{data[start+8],
 | 
				
			||||||
            data[start+9], data[start+10], data[start+11]}))
 | 
					                data[start+9], data[start+10], data[start+11]}))
 | 
				
			||||||
            total := l + 12
 | 
					            total := l + common.PACKET_LEN
 | 
				
			||||||
            if total == tl { // data is what we want
 | 
					            if total == tl { // data is what we want
 | 
				
			||||||
                return
 | 
					                return data, common.PACKET_LEN, true
 | 
				
			||||||
            } else if total < tl{ // data[:total] is what we want, data[total:] is the more 
 | 
					            } else if total < tl { // data[:total] is what we want, data[total:] is the more 
 | 
				
			||||||
                a.in <- data[total:]
 | 
					                a.in <- data[total:]
 | 
				
			||||||
                data = data[:total]
 | 
					                data = data[:total]
 | 
				
			||||||
                return
 | 
					                return data, common.PACKET_LEN, true
 | 
				
			||||||
            } else { // ops! It won't be possible.
 | 
					            } else { // ops! It won't be possible.
 | 
				
			||||||
                goto BEGIN
 | 
					                return nil, total - tl, false
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else { // flag was not found, move to next step
 | 
					        } else { // flag was not found, move to next step
 | 
				
			||||||
            start++
 | 
					            start++
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    goto BEGIN
 | 
					    return nil, common.PACKET_LEN, false
 | 
				
			||||||
    return nil, common.Errorf("Invalid data: %V", data)
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *agent) read() (rel []byte, err error) {
 | 
				
			||||||
 | 
					    var data []byte
 | 
				
			||||||
 | 
					    ok := false
 | 
				
			||||||
 | 
					    l := common.PACKET_LEN
 | 
				
			||||||
 | 
					    for !ok {
 | 
				
			||||||
 | 
					        inlen := len(a.in)
 | 
				
			||||||
 | 
					        if inlen > 0 {
 | 
				
			||||||
 | 
					            // in queue is not empty
 | 
				
			||||||
 | 
					            for i := 0; i < inlen; i++ {
 | 
				
			||||||
 | 
					                data = append(data, <-a.in...)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            var d []byte
 | 
				
			||||||
 | 
					            d, err = a.readData(l)
 | 
				
			||||||
 | 
					            if err != nil {
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            data = append(data, d...)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        rel, l, ok = a.unpack(data)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Send a job to the job server.
 | 
					// Send a job to the job server.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user