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.
 
 
 

111 lines
2.5 KiB

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