You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

agent.go 2.3 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2011 Xing Xing <mikespook@gmail.com> All rights reserved.
  2. // Use of this source code is governed by a MIT
  3. // license that can be found in the LICENSE file.
  4. package worker
  5. import (
  6. "io"
  7. "net"
  8. )
  9. // The agent of job server.
  10. type agent struct {
  11. conn net.Conn
  12. worker *Worker
  13. in chan []byte
  14. net, addr string
  15. isConn bool
  16. }
  17. // Create the agent of job server.
  18. func newAgent(net, addr string, worker *Worker) (a *agent, err error) {
  19. a = &agent{
  20. net: net,
  21. addr: addr,
  22. worker: worker,
  23. in: make(chan []byte, QUEUE_SIZE),
  24. }
  25. return
  26. }
  27. func (a *agent) Connect() (err error) {
  28. a.conn, err = net.Dial(a.net, a.addr)
  29. if err != nil {
  30. return
  31. }
  32. a.isConn = true
  33. return
  34. }
  35. func (a *agent) Work() {
  36. go a.readLoop()
  37. var resp *Response
  38. var l int
  39. var err error
  40. var data, leftdata []byte
  41. for data = range a.in {
  42. if len(leftdata) > 0 { // some data left for processing
  43. data = append(leftdata, data...)
  44. }
  45. l = len(data)
  46. if l < MIN_PACKET_LEN { // not enough data
  47. leftdata = data
  48. continue
  49. }
  50. if resp, l, err = decodeResponse(data); err != nil {
  51. a.worker.err(err)
  52. continue
  53. }
  54. leftdata = nil
  55. resp.agentId = a.net + a.addr
  56. a.worker.in <- resp
  57. if len(data) > l {
  58. leftdata = data[l:]
  59. }
  60. }
  61. }
  62. // read data from socket
  63. func (a *agent) readLoop() {
  64. var data []byte
  65. var err error
  66. for a.isConn {
  67. if data, err = a.read(BUFFER_SIZE); err != nil {
  68. if err == ErrConnClosed {
  69. break
  70. }
  71. a.worker.err(err)
  72. continue
  73. }
  74. a.in <- data
  75. }
  76. close(a.in)
  77. }
  78. func (a *agent) Close() {
  79. a.conn.Close()
  80. }
  81. // read length bytes from the socket
  82. func (a *agent) read(length int) (data []byte, err error) {
  83. n := 0
  84. buf := getBuffer(BUFFER_SIZE)
  85. // read until data can be unpacked
  86. for i := length; i > 0 || len(data) < MIN_PACKET_LEN; i -= n {
  87. if n, err = a.conn.Read(buf); err != nil {
  88. if !a.isConn {
  89. err = ErrConnClosed
  90. return
  91. }
  92. if err == io.EOF && n == 0 {
  93. if data == nil {
  94. err = ErrConnection
  95. }
  96. }
  97. return
  98. }
  99. data = append(data, buf[0:n]...)
  100. if n < BUFFER_SIZE {
  101. break
  102. }
  103. }
  104. return
  105. }
  106. // Internal write the encoded job.
  107. func (a *agent) write(req *request) (err error) {
  108. var n int
  109. buf := req.Encode()
  110. for i := 0; i < len(buf); i += n {
  111. n, err = a.conn.Write(buf[i:])
  112. if err != nil {
  113. return err
  114. }
  115. }
  116. return
  117. }