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
10 years ago
11 years ago
10 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. }
  16. // Create the agent of job server.
  17. func newAgent(net, addr string, worker *Worker) (a *agent, err error) {
  18. a = &agent{
  19. net: net,
  20. addr: addr,
  21. worker: worker,
  22. in: make(chan []byte, QUEUE_SIZE),
  23. }
  24. return
  25. }
  26. func (a *agent) Connect() (err error) {
  27. a.conn, err = net.Dial(a.net, a.addr)
  28. if err != nil {
  29. return
  30. }
  31. go a.work()
  32. return
  33. }
  34. func (a *agent) work() {
  35. var inpack *inPack
  36. var l int
  37. var err error
  38. var data, leftdata []byte
  39. for {
  40. if data, err = a.read(BUFFER_SIZE); err != nil {
  41. if err == ErrConnClosed {
  42. break
  43. }
  44. a.worker.err(err)
  45. continue
  46. }
  47. if len(leftdata) > 0 { // some data left for processing
  48. data = append(leftdata, data...)
  49. }
  50. if len(data) < MIN_PACKET_LEN { // not enough data
  51. leftdata = data
  52. continue
  53. }
  54. if inpack, l, err = decodeInPack(data); err != nil {
  55. a.worker.err(err)
  56. continue
  57. }
  58. leftdata = nil
  59. inpack.a = a
  60. a.worker.in <- inpack
  61. if len(data) > l {
  62. leftdata = data[l:]
  63. }
  64. }
  65. }
  66. func (a *agent) Close() {
  67. a.conn.Close()
  68. }
  69. func (a *agent) Grab() {
  70. outpack := getOutPack()
  71. outpack.dataType = GRAB_JOB_UNIQ
  72. a.write(outpack)
  73. }
  74. func (a *agent) PreSleep() {
  75. outpack := getOutPack()
  76. outpack.dataType = PRE_SLEEP
  77. a.write(outpack)
  78. }
  79. // read length bytes from the socket
  80. func (a *agent) read(length int) (data []byte, err error) {
  81. n := 0
  82. buf := getBuffer(BUFFER_SIZE)
  83. // read until data can be unpacked
  84. for i := length; i > 0 || len(data) < MIN_PACKET_LEN; i -= n {
  85. if n, err = a.conn.Read(buf); err != nil {
  86. if err == io.EOF && n == 0 {
  87. if data == nil {
  88. err = ErrConnection
  89. } else {
  90. err = ErrConnClosed
  91. }
  92. }
  93. return
  94. }
  95. data = append(data, buf[0:n]...)
  96. if n < BUFFER_SIZE {
  97. break
  98. }
  99. }
  100. return
  101. }
  102. // Internal write the encoded job.
  103. func (a *agent) write(outpack *outPack) (err error) {
  104. var n int
  105. buf := outpack.Encode()
  106. for i := 0; i < len(buf); i += n {
  107. n, err = a.conn.Write(buf[i:])
  108. if err != nil {
  109. return err
  110. }
  111. }
  112. return
  113. }