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.

job.go 3.6 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12 years ago
12 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. "strconv"
  9. "github.com/mikespook/gearman-go/common"
  10. )
  11. // Worker side job
  12. type Job struct {
  13. Data []byte
  14. Handle, UniqueId, Fn string
  15. agent *agent
  16. magicCode, DataType uint32
  17. c chan bool
  18. }
  19. // Create a new job
  20. func newJob(magiccode, datatype uint32, data []byte) (job *Job) {
  21. return &Job{magicCode: magiccode,
  22. DataType: datatype,
  23. Data: data,
  24. c: make(chan bool),}
  25. }
  26. // Decode job from byte slice
  27. func decodeJob(data []byte) (job *Job, err error) {
  28. if len(data) < 12 {
  29. return nil, common.Errorf("Invalid data: %V", data)
  30. }
  31. datatype := common.BytesToUint32([4]byte{data[4], data[5], data[6], data[7]})
  32. l := common.BytesToUint32([4]byte{data[8], data[9], data[10], data[11]})
  33. if len(data[12:]) != int(l) {
  34. return nil, common.Errorf("Invalid data: %V", data)
  35. }
  36. data = data[12:]
  37. job = &Job{magicCode: common.RES, DataType: datatype, c: make(chan bool),}
  38. switch datatype {
  39. case common.JOB_ASSIGN:
  40. s := bytes.SplitN(data, []byte{'\x00'}, 3)
  41. if len(s) == 3 {
  42. job.Handle = string(s[0])
  43. job.Fn = string(s[1])
  44. data = s[2]
  45. }
  46. case common.JOB_ASSIGN_UNIQ:
  47. s := bytes.SplitN(data, []byte{'\x00'}, 4)
  48. if len(s) == 4 {
  49. job.Handle = string(s[0])
  50. job.Fn = string(s[1])
  51. job.UniqueId = string(s[2])
  52. data = s[3]
  53. }
  54. }
  55. job.Data = data
  56. return
  57. }
  58. // Encode a job to byte slice
  59. func (job *Job) Encode() (data []byte) {
  60. var l int
  61. if job.DataType == common.WORK_FAIL {
  62. l = len(job.Handle)
  63. } else {
  64. l = len(job.Data)
  65. if job.Handle != "" {
  66. l += len(job.Handle) + 1
  67. }
  68. }
  69. data = make([]byte, 0, l + 12)
  70. magiccode := common.Uint32ToBytes(job.magicCode)
  71. datatype := common.Uint32ToBytes(job.DataType)
  72. datalength := common.Uint32ToBytes(uint32(l))
  73. data = append(data, magiccode[:]...)
  74. data = append(data, datatype[:]...)
  75. data = append(data, datalength[:]...)
  76. if job.Handle != "" {
  77. data = append(data, []byte(job.Handle)...)
  78. if job.DataType != common.WORK_FAIL {
  79. data = append(data, 0)
  80. }
  81. }
  82. data = append(data, job.Data...)
  83. return
  84. }
  85. // Send some datas to client.
  86. // Using this in a job's executing.
  87. func (job *Job) UpdateData(data []byte, iswarning bool) {
  88. result := append([]byte(job.Handle), 0)
  89. result = append(result, data...)
  90. var datatype uint32
  91. if iswarning {
  92. datatype = common.WORK_WARNING
  93. } else {
  94. datatype = common.WORK_DATA
  95. }
  96. job.agent.WriteJob(newJob(common.REQ, datatype, result))
  97. }
  98. // Update status.
  99. // Tall client how many percent job has been executed.
  100. func (job *Job) UpdateStatus(numerator, denominator int) {
  101. n := []byte(strconv.Itoa(numerator))
  102. d := []byte(strconv.Itoa(denominator))
  103. result := append([]byte(job.Handle), '\x00')
  104. result = append(result, n...)
  105. result = append(result, '\x00')
  106. result = append(result, d...)
  107. job.agent.WriteJob(newJob(common.REQ, common.WORK_STATUS, result))
  108. }
  109. // close the job
  110. func (job *Job) Close() {
  111. close(job.c)
  112. }
  113. // cancel the job executing
  114. func (job *Job) cancel() {
  115. defer func() {recover()}()
  116. job.c <- true
  117. }
  118. // When a job was canceled, return a true form a channel
  119. func (job *Job) Canceled() <-chan bool {
  120. return job.c
  121. }