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.
 
 
 

129 lines
2.3 KiB

  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. }