- // Copyright 2011 Xing Xing <mikespook@gmail.com> All rights reserved.
- // Use of this source code is governed by a MIT
- // license that can be found in the LICENSE file.
-
- package worker
-
- import (
- "io"
- "net"
- )
-
- // The agent of job server.
- type agent struct {
- conn net.Conn
- worker *Worker
- in chan []byte
- net, addr string
- }
-
- // Create the agent of job server.
- func newAgent(net, addr string, worker *Worker) (a *agent, err error) {
- a = &agent{
- net: net,
- addr: addr,
- worker: worker,
- in: make(chan []byte, QUEUE_SIZE),
- }
- return
- }
-
- func (a *agent) Connect() (err error) {
- a.conn, err = net.Dial(a.net, a.addr)
- if err != nil {
- return
- }
- go a.work()
- return
- }
-
- func (a *agent) work() {
- var inpack *inPack
- var l int
- var err error
- var data, leftdata []byte
- for {
- if data, err = a.read(BUFFER_SIZE); err != nil {
- if err == ErrConnClosed {
- break
- }
- a.worker.err(err)
- continue
- }
- if len(leftdata) > 0 { // some data left for processing
- data = append(leftdata, data...)
- }
- if len(data) < MIN_PACKET_LEN { // not enough data
- leftdata = data
- continue
- }
- if inpack, l, err = decodeInPack(data); err != nil {
- a.worker.err(err)
- continue
- }
- leftdata = nil
- inpack.a = a
- a.worker.in <- inpack
- if len(data) > l {
- leftdata = data[l:]
- }
- }
- }
-
- func (a *agent) Close() {
- a.conn.Close()
- }
-
- func (a *agent) Grab() {
- outpack := getOutPack()
- outpack.dataType = GRAB_JOB_UNIQ
- a.write(outpack)
- }
-
- func (a *agent) PreSleep() {
- outpack := getOutPack()
- outpack.dataType = PRE_SLEEP
- a.write(outpack)
- }
-
- // read length bytes from the socket
- func (a *agent) read(length int) (data []byte, err error) {
- n := 0
- buf := getBuffer(BUFFER_SIZE)
- // read until data can be unpacked
- for i := length; i > 0 || len(data) < MIN_PACKET_LEN; i -= n {
- if n, err = a.conn.Read(buf); err != nil {
- if err == io.EOF && n == 0 {
- if data == nil {
- err = ErrConnection
- } else {
- err = ErrConnClosed
- }
- }
- return
- }
- data = append(data, buf[0:n]...)
- if n < BUFFER_SIZE {
- break
- }
- }
- return
- }
-
- // Internal write the encoded job.
- func (a *agent) write(outpack *outPack) (err error) {
- var n int
- buf := outpack.Encode()
- for i := 0; i < len(buf); i += n {
- n, err = a.conn.Write(buf[i:])
- if err != nil {
- return err
- }
- }
- return
- }
|