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.
 
 
 

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