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.
 
 
 

109 lines
2.6 KiB

  1. // Copyright 2011 Xing Xing <mikespook@gmail.com>
  2. // All rights reserved.
  3. // Use of this source code is governed by a MIT
  4. // license that can be found in the LICENSE file.
  5. package worker
  6. import (
  7. "bytes"
  8. "encoding/binary"
  9. "fmt"
  10. "strconv"
  11. )
  12. // Worker side job
  13. type inPack struct {
  14. dataType uint32
  15. data []byte
  16. handle, uniqueId, fn string
  17. a *agent
  18. }
  19. // Create a new job
  20. func getInPack() *inPack {
  21. return &inPack{}
  22. }
  23. func (inpack *inPack) Data() []byte {
  24. return inpack.data
  25. }
  26. // Send some datas to client.
  27. // Using this in a job's executing.
  28. func (inpack *inPack) SendData(data []byte) {
  29. outpack := getOutPack()
  30. outpack.dataType = WORK_DATA
  31. hl := len(inpack.handle)
  32. l := hl + len(data) + 1
  33. outpack.data = getBuffer(l)
  34. copy(outpack.data, []byte(inpack.handle))
  35. copy(outpack.data[hl+1:], data)
  36. inpack.a.write(outpack)
  37. }
  38. func (inpack *inPack) SendWarning(data []byte) {
  39. outpack := getOutPack()
  40. outpack.dataType = WORK_WARNING
  41. hl := len(inpack.handle)
  42. l := hl + len(data) + 1
  43. outpack.data = getBuffer(l)
  44. copy(outpack.data, []byte(inpack.handle))
  45. copy(outpack.data[hl+1:], data)
  46. inpack.a.write(outpack)
  47. }
  48. // Update status.
  49. // Tall client how many percent job has been executed.
  50. func (inpack *inPack) UpdateStatus(numerator, denominator int) {
  51. n := []byte(strconv.Itoa(numerator))
  52. d := []byte(strconv.Itoa(denominator))
  53. outpack := getOutPack()
  54. outpack.dataType = WORK_STATUS
  55. hl := len(inpack.handle)
  56. nl := len(n)
  57. dl := len(d)
  58. outpack.data = getBuffer(hl + nl + dl + 3)
  59. copy(outpack.data, []byte(inpack.handle))
  60. copy(outpack.data[hl+1:], n)
  61. copy(outpack.data[hl+nl+2:], d)
  62. inpack.a.write(outpack)
  63. }
  64. // Decode job from byte slice
  65. func decodeInPack(data []byte) (inpack *inPack, l int, err error) {
  66. if len(data) < MIN_PACKET_LEN { // valid package should not less 12 bytes
  67. err = fmt.Errorf("Invalid data: %V", data)
  68. return
  69. }
  70. dl := int(binary.BigEndian.Uint32(data[8:12]))
  71. dt := data[MIN_PACKET_LEN : dl+MIN_PACKET_LEN]
  72. if len(dt) != int(dl) { // length not equal
  73. err = fmt.Errorf("Invalid data: %V", data)
  74. return
  75. }
  76. inpack = getInPack()
  77. inpack.dataType = binary.BigEndian.Uint32(data[4:8])
  78. switch inpack.dataType {
  79. case JOB_ASSIGN:
  80. s := bytes.SplitN(dt, []byte{'\x00'}, 3)
  81. if len(s) == 3 {
  82. inpack.handle = string(s[0])
  83. inpack.fn = string(s[1])
  84. inpack.data = s[2]
  85. }
  86. case JOB_ASSIGN_UNIQ:
  87. s := bytes.SplitN(dt, []byte{'\x00'}, 4)
  88. if len(s) == 4 {
  89. inpack.handle = string(s[0])
  90. inpack.fn = string(s[1])
  91. inpack.uniqueId = string(s[2])
  92. inpack.data = s[3]
  93. }
  94. default:
  95. inpack.data = dt
  96. }
  97. l = dl + MIN_PACKET_LEN
  98. return
  99. }