bullmq 5.44.1 → 5.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/dist/cjs/classes/async-fifo-queue.js.map +1 -1
  2. package/dist/cjs/classes/child-processor.js.map +1 -1
  3. package/dist/cjs/classes/child.js.map +1 -1
  4. package/dist/cjs/classes/flow-producer.js +15 -4
  5. package/dist/cjs/classes/flow-producer.js.map +1 -1
  6. package/dist/cjs/classes/job-scheduler.js +1 -1
  7. package/dist/cjs/classes/job-scheduler.js.map +1 -1
  8. package/dist/cjs/classes/job.js +137 -54
  9. package/dist/cjs/classes/job.js.map +1 -1
  10. package/dist/cjs/classes/queue-base.js +1 -4
  11. package/dist/cjs/classes/queue-base.js.map +1 -1
  12. package/dist/cjs/classes/queue-events-producer.js.map +1 -1
  13. package/dist/cjs/classes/queue-events.js.map +1 -1
  14. package/dist/cjs/classes/queue-getters.js +12 -15
  15. package/dist/cjs/classes/queue-getters.js.map +1 -1
  16. package/dist/cjs/classes/queue-keys.js.map +1 -1
  17. package/dist/cjs/classes/queue.js +12 -13
  18. package/dist/cjs/classes/queue.js.map +1 -1
  19. package/dist/cjs/classes/redis-connection.js +1 -1
  20. package/dist/cjs/classes/redis-connection.js.map +1 -1
  21. package/dist/cjs/classes/repeat.js +1 -1
  22. package/dist/cjs/classes/repeat.js.map +1 -1
  23. package/dist/cjs/classes/scripts.js +18 -7
  24. package/dist/cjs/classes/scripts.js.map +1 -1
  25. package/dist/cjs/classes/worker.js +4 -0
  26. package/dist/cjs/classes/worker.js.map +1 -1
  27. package/dist/cjs/commands/addJobScheduler-11.lua +52 -33
  28. package/dist/cjs/commands/includes/deduplicateJob.lua +16 -17
  29. package/dist/cjs/commands/includes/isLocked.lua +1 -0
  30. package/dist/cjs/commands/includes/moveChildFromDependenciesIfNeeded.lua +79 -0
  31. package/dist/cjs/commands/includes/moveParentToWait.lua +48 -0
  32. package/dist/cjs/commands/includes/moveParentToWaitIfNeeded.lua +9 -50
  33. package/dist/cjs/commands/includes/moveParentToWaitIfNoPendingDependencies.lua +13 -0
  34. package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeededOnFinalization.lua +23 -0
  35. package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeededOnRemoval.lua +16 -0
  36. package/dist/cjs/commands/includes/removeJob.lua +2 -2
  37. package/dist/cjs/commands/includes/removeJobWithChildren.lua +94 -0
  38. package/dist/cjs/commands/includes/removeParentDependencyKey.lua +5 -5
  39. package/dist/cjs/commands/includes/storeJob.lua +1 -1
  40. package/dist/cjs/commands/includes/updateParentDepsIfNeeded.lua +2 -2
  41. package/dist/cjs/commands/moveStalledJobsToWait-9.lua +18 -53
  42. package/dist/cjs/commands/moveToFinished-14.lua +43 -51
  43. package/dist/cjs/commands/moveToWaitingChildren-8.lua +5 -32
  44. package/dist/cjs/commands/removeJob-3.lua +14 -72
  45. package/dist/cjs/commands/removeUnprocessedChildren-2.lua +31 -0
  46. package/dist/cjs/commands/updateJobScheduler-12.lua +29 -23
  47. package/dist/cjs/scripts/addDelayedJob-6.js +73 -55
  48. package/dist/cjs/scripts/addDelayedJob-6.js.map +1 -1
  49. package/dist/cjs/scripts/addJobScheduler-11.js +59 -40
  50. package/dist/cjs/scripts/addJobScheduler-11.js.map +1 -1
  51. package/dist/cjs/scripts/addParentJob-4.js +73 -55
  52. package/dist/cjs/scripts/addParentJob-4.js.map +1 -1
  53. package/dist/cjs/scripts/addPrioritizedJob-8.js +73 -55
  54. package/dist/cjs/scripts/addPrioritizedJob-8.js.map +1 -1
  55. package/dist/cjs/scripts/addRepeatableJob-2.js +14 -9
  56. package/dist/cjs/scripts/addRepeatableJob-2.js.map +1 -1
  57. package/dist/cjs/scripts/addStandardJob-8.js +73 -55
  58. package/dist/cjs/scripts/addStandardJob-8.js.map +1 -1
  59. package/dist/cjs/scripts/cleanJobsInSet-3.js +14 -9
  60. package/dist/cjs/scripts/cleanJobsInSet-3.js.map +1 -1
  61. package/dist/cjs/scripts/drain-5.js +14 -9
  62. package/dist/cjs/scripts/drain-5.js.map +1 -1
  63. package/dist/cjs/scripts/index.js +1 -0
  64. package/dist/cjs/scripts/index.js.map +1 -1
  65. package/dist/cjs/scripts/moveStalledJobsToWait-9.js +157 -155
  66. package/dist/cjs/scripts/moveStalledJobsToWait-9.js.map +1 -1
  67. package/dist/cjs/scripts/moveToFinished-14.js +183 -157
  68. package/dist/cjs/scripts/moveToFinished-14.js.map +1 -1
  69. package/dist/cjs/scripts/moveToWaitingChildren-8.js +145 -137
  70. package/dist/cjs/scripts/moveToWaitingChildren-8.js.map +1 -1
  71. package/dist/cjs/scripts/obliterate-2.js +14 -9
  72. package/dist/cjs/scripts/obliterate-2.js.map +1 -1
  73. package/dist/cjs/scripts/removeChildDependency-1.js +5 -5
  74. package/dist/cjs/scripts/removeJob-3.js +97 -63
  75. package/dist/cjs/scripts/removeJob-3.js.map +1 -1
  76. package/dist/cjs/scripts/removeUnprocessedChildren-2.js +338 -0
  77. package/dist/cjs/scripts/removeUnprocessedChildren-2.js.map +1 -0
  78. package/dist/cjs/scripts/updateJobScheduler-12.js +27 -21
  79. package/dist/cjs/scripts/updateJobScheduler-12.js.map +1 -1
  80. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  81. package/dist/cjs/types/index.js +1 -0
  82. package/dist/cjs/types/index.js.map +1 -1
  83. package/dist/cjs/types/job-progress.js +3 -0
  84. package/dist/cjs/types/job-progress.js.map +1 -0
  85. package/dist/cjs/utils.js +12 -1
  86. package/dist/cjs/utils.js.map +1 -1
  87. package/dist/cjs/version.js +1 -1
  88. package/dist/esm/classes/async-fifo-queue.js.map +1 -1
  89. package/dist/esm/classes/child-processor.js.map +1 -1
  90. package/dist/esm/classes/child.js.map +1 -1
  91. package/dist/esm/classes/flow-producer.js +15 -4
  92. package/dist/esm/classes/flow-producer.js.map +1 -1
  93. package/dist/esm/classes/job-scheduler.js +1 -1
  94. package/dist/esm/classes/job-scheduler.js.map +1 -1
  95. package/dist/esm/classes/job.d.ts +49 -14
  96. package/dist/esm/classes/job.js +138 -55
  97. package/dist/esm/classes/job.js.map +1 -1
  98. package/dist/esm/classes/queue-base.d.ts +1 -4
  99. package/dist/esm/classes/queue-base.js +1 -4
  100. package/dist/esm/classes/queue-base.js.map +1 -1
  101. package/dist/esm/classes/queue-events-producer.d.ts +2 -2
  102. package/dist/esm/classes/queue-events-producer.js.map +1 -1
  103. package/dist/esm/classes/queue-events.d.ts +118 -29
  104. package/dist/esm/classes/queue-events.js.map +1 -1
  105. package/dist/esm/classes/queue-getters.d.ts +11 -14
  106. package/dist/esm/classes/queue-getters.js +12 -15
  107. package/dist/esm/classes/queue-getters.js.map +1 -1
  108. package/dist/esm/classes/queue-keys.js.map +1 -1
  109. package/dist/esm/classes/queue.d.ts +14 -15
  110. package/dist/esm/classes/queue.js +12 -13
  111. package/dist/esm/classes/queue.js.map +1 -1
  112. package/dist/esm/classes/redis-connection.js +1 -1
  113. package/dist/esm/classes/redis-connection.js.map +1 -1
  114. package/dist/esm/classes/repeat.js +1 -1
  115. package/dist/esm/classes/repeat.js.map +1 -1
  116. package/dist/esm/classes/scripts.d.ts +4 -3
  117. package/dist/esm/classes/scripts.js +18 -7
  118. package/dist/esm/classes/scripts.js.map +1 -1
  119. package/dist/esm/classes/worker.d.ts +2 -1
  120. package/dist/esm/classes/worker.js +5 -1
  121. package/dist/esm/classes/worker.js.map +1 -1
  122. package/dist/esm/commands/addJobScheduler-11.lua +52 -33
  123. package/dist/esm/commands/includes/deduplicateJob.lua +16 -17
  124. package/dist/esm/commands/includes/isLocked.lua +1 -0
  125. package/dist/esm/commands/includes/moveChildFromDependenciesIfNeeded.lua +79 -0
  126. package/dist/esm/commands/includes/moveParentToWait.lua +48 -0
  127. package/dist/esm/commands/includes/moveParentToWaitIfNeeded.lua +9 -50
  128. package/dist/esm/commands/includes/moveParentToWaitIfNoPendingDependencies.lua +13 -0
  129. package/dist/esm/commands/includes/removeDeduplicationKeyIfNeededOnFinalization.lua +23 -0
  130. package/dist/esm/commands/includes/removeDeduplicationKeyIfNeededOnRemoval.lua +16 -0
  131. package/dist/esm/commands/includes/removeJob.lua +2 -2
  132. package/dist/esm/commands/includes/removeJobWithChildren.lua +94 -0
  133. package/dist/esm/commands/includes/removeParentDependencyKey.lua +5 -5
  134. package/dist/esm/commands/includes/storeJob.lua +1 -1
  135. package/dist/esm/commands/includes/updateParentDepsIfNeeded.lua +2 -2
  136. package/dist/esm/commands/moveStalledJobsToWait-9.lua +18 -53
  137. package/dist/esm/commands/moveToFinished-14.lua +43 -51
  138. package/dist/esm/commands/moveToWaitingChildren-8.lua +5 -32
  139. package/dist/esm/commands/removeJob-3.lua +14 -72
  140. package/dist/esm/commands/removeUnprocessedChildren-2.lua +31 -0
  141. package/dist/esm/commands/updateJobScheduler-12.lua +29 -23
  142. package/dist/esm/interfaces/job-json.d.ts +5 -2
  143. package/dist/esm/interfaces/minimal-job.d.ts +29 -11
  144. package/dist/esm/interfaces/queue-options.d.ts +6 -2
  145. package/dist/esm/interfaces/repeat-options.d.ts +1 -1
  146. package/dist/esm/interfaces/sandboxed-job.d.ts +2 -2
  147. package/dist/esm/interfaces/sandboxed-options.d.ts +1 -1
  148. package/dist/esm/interfaces/telemetry.d.ts +18 -15
  149. package/dist/esm/interfaces/worker-options.d.ts +10 -10
  150. package/dist/esm/scripts/addDelayedJob-6.js +73 -55
  151. package/dist/esm/scripts/addDelayedJob-6.js.map +1 -1
  152. package/dist/esm/scripts/addJobScheduler-11.js +59 -40
  153. package/dist/esm/scripts/addJobScheduler-11.js.map +1 -1
  154. package/dist/esm/scripts/addParentJob-4.js +73 -55
  155. package/dist/esm/scripts/addParentJob-4.js.map +1 -1
  156. package/dist/esm/scripts/addPrioritizedJob-8.js +73 -55
  157. package/dist/esm/scripts/addPrioritizedJob-8.js.map +1 -1
  158. package/dist/esm/scripts/addRepeatableJob-2.js +14 -9
  159. package/dist/esm/scripts/addRepeatableJob-2.js.map +1 -1
  160. package/dist/esm/scripts/addStandardJob-8.js +73 -55
  161. package/dist/esm/scripts/addStandardJob-8.js.map +1 -1
  162. package/dist/esm/scripts/cleanJobsInSet-3.js +14 -9
  163. package/dist/esm/scripts/cleanJobsInSet-3.js.map +1 -1
  164. package/dist/esm/scripts/drain-5.js +14 -9
  165. package/dist/esm/scripts/drain-5.js.map +1 -1
  166. package/dist/esm/scripts/index.d.ts +1 -0
  167. package/dist/esm/scripts/index.js +1 -0
  168. package/dist/esm/scripts/index.js.map +1 -1
  169. package/dist/esm/scripts/moveStalledJobsToWait-9.js +157 -155
  170. package/dist/esm/scripts/moveStalledJobsToWait-9.js.map +1 -1
  171. package/dist/esm/scripts/moveToFinished-14.js +183 -157
  172. package/dist/esm/scripts/moveToFinished-14.js.map +1 -1
  173. package/dist/esm/scripts/moveToWaitingChildren-8.js +145 -137
  174. package/dist/esm/scripts/moveToWaitingChildren-8.js.map +1 -1
  175. package/dist/esm/scripts/obliterate-2.js +14 -9
  176. package/dist/esm/scripts/obliterate-2.js.map +1 -1
  177. package/dist/esm/scripts/removeChildDependency-1.js +5 -5
  178. package/dist/esm/scripts/removeJob-3.js +97 -63
  179. package/dist/esm/scripts/removeJob-3.js.map +1 -1
  180. package/dist/esm/scripts/removeUnprocessedChildren-2.d.ts +5 -0
  181. package/dist/esm/scripts/removeUnprocessedChildren-2.js +335 -0
  182. package/dist/esm/scripts/removeUnprocessedChildren-2.js.map +1 -0
  183. package/dist/esm/scripts/updateJobScheduler-12.js +27 -21
  184. package/dist/esm/scripts/updateJobScheduler-12.js.map +1 -1
  185. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  186. package/dist/esm/types/index.d.ts +1 -0
  187. package/dist/esm/types/index.js +1 -0
  188. package/dist/esm/types/index.js.map +1 -1
  189. package/dist/esm/types/job-options.d.ts +13 -2
  190. package/dist/esm/types/job-progress.d.ts +1 -0
  191. package/dist/esm/types/job-progress.js +2 -0
  192. package/dist/esm/types/job-progress.js.map +1 -0
  193. package/dist/esm/utils.d.ts +17 -0
  194. package/dist/esm/utils.js +11 -0
  195. package/dist/esm/utils.js.map +1 -1
  196. package/dist/esm/version.d.ts +1 -1
  197. package/dist/esm/version.js +1 -1
  198. package/package.json +26 -21
  199. package/dist/cjs/commands/includes/moveParentFromWaitingChildrenToFailed.lua +0 -80
  200. package/dist/cjs/commands/includes/removeDeduplicationKey.lua +0 -11
  201. package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeeded.lua +0 -14
  202. package/dist/esm/commands/includes/moveParentFromWaitingChildrenToFailed.lua +0 -80
  203. package/dist/esm/commands/includes/removeDeduplicationKey.lua +0 -11
  204. package/dist/esm/commands/includes/removeDeduplicationKeyIfNeeded.lua +0 -14
@@ -1,38 +1,18 @@
1
1
  const content = `--[[
2
- Remove a job from all the queues it may be in as well as all its data.
2
+ Remove a job from all the statuses it may be in as well as all its data.
3
3
  In order to be able to remove a job, it cannot be active.
4
4
  Input:
5
- KEYS[1] queue prefix
5
+ KEYS[1] jobKey
6
6
  KEYS[2] meta key
7
7
  KEYS[3] repeat key
8
8
  ARGV[1] jobId
9
9
  ARGV[2] remove children
10
+ ARGV[3] queue prefix
10
11
  Events:
11
12
  'removed'
12
13
  ]]
13
14
  local rcall = redis.call
14
15
  -- Includes
15
- --[[
16
- Functions to destructure job key.
17
- Just a bit of warning, these functions may be a bit slow and affect performance significantly.
18
- ]]
19
- local getJobIdFromKey = function (jobKey)
20
- return string.match(jobKey, ".*:(.*)")
21
- end
22
- local getJobKeyPrefix = function (jobKey, jobId)
23
- return string.sub(jobKey, 0, #jobKey - #jobId)
24
- end
25
- --[[
26
- Function to get max events value or set by default 10000.
27
- ]]
28
- local function getOrSetMaxEvents(metaKey)
29
- local maxEvents = rcall("HGET", metaKey, "opts.maxLenEvents")
30
- if not maxEvents then
31
- maxEvents = 10000
32
- rcall("HSET", metaKey, "opts.maxLenEvents", maxEvents)
33
- end
34
- return maxEvents
35
- end
36
16
  --[[
37
17
  Function to check if the job belongs to a job scheduler and
38
18
  current delayed job matches with jobId
@@ -54,6 +34,16 @@ end
54
34
  returns:
55
35
  boolean
56
36
  ]]
37
+ --[[
38
+ Functions to destructure job key.
39
+ Just a bit of warning, these functions may be a bit slow and affect performance significantly.
40
+ ]]
41
+ local getJobIdFromKey = function (jobKey)
42
+ return string.match(jobKey, ".*:(.*)")
43
+ end
44
+ local getJobKeyPrefix = function (jobKey, jobId)
45
+ return string.sub(jobKey, 0, #jobKey - #jobId)
46
+ end
57
47
  local function isLocked( prefix, jobId, removeChildren)
58
48
  local jobKey = prefix .. jobId;
59
49
  -- Check if this job is locked
@@ -79,13 +69,37 @@ local function isLocked( prefix, jobId, removeChildren)
79
69
  return true
80
70
  end
81
71
  --[[
82
- Function to remove deduplication key.
72
+ Remove a job from all the statuses it may be in as well as all its data,
73
+ including its children. Active children can be ignored.
74
+ Events:
75
+ 'removed'
76
+ ]]
77
+ local rcall = redis.call
78
+ -- Includes
79
+ --[[
80
+ Function to get max events value or set by default 10000.
81
+ ]]
82
+ local function getOrSetMaxEvents(metaKey)
83
+ local maxEvents = rcall("HGET", metaKey, "opts.maxLenEvents")
84
+ if not maxEvents then
85
+ maxEvents = 10000
86
+ rcall("HSET", metaKey, "opts.maxLenEvents", maxEvents)
87
+ end
88
+ return maxEvents
89
+ end
90
+ --[[
91
+ Function to remove deduplication key if needed
92
+ when a job is being removed.
83
93
  ]]
84
- local function removeDeduplicationKey(prefixKey, jobKey)
94
+ local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
95
+ jobKey, jobId)
85
96
  local deduplicationId = rcall("HGET", jobKey, "deid")
86
97
  if deduplicationId then
87
98
  local deduplicationKey = prefixKey .. "de:" .. deduplicationId
88
- rcall("DEL", deduplicationKey)
99
+ local currentJobId = rcall('GET', deduplicationKey)
100
+ if currentJobId and currentJobId == jobId then
101
+ return rcall("DEL", deduplicationKey)
102
+ end
89
103
  end
90
104
  end
91
105
  --[[
@@ -169,7 +183,7 @@ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
169
183
  end
170
184
  return waitKey, false
171
185
  end
172
- local function moveParentToWait(parentPrefix, parentId, emitEvent)
186
+ local function _moveParentToWait(parentPrefix, parentId, emitEvent)
173
187
  local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
174
188
  parentPrefix .. "wait", parentPrefix .. "paused")
175
189
  addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
@@ -197,10 +211,10 @@ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debou
197
211
  rcall("DEL", parentPrefix .. "de:" .. debounceId)
198
212
  end
199
213
  else
200
- moveParentToWait(parentPrefix, parentId)
214
+ _moveParentToWait(parentPrefix, parentId)
201
215
  end
202
216
  else
203
- moveParentToWait(parentPrefix, parentId, true)
217
+ _moveParentToWait(parentPrefix, parentId, true)
204
218
  end
205
219
  end
206
220
  end
@@ -228,10 +242,10 @@ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debou
228
242
  rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
229
243
  end
230
244
  else
231
- moveParentToWait(parentPrefix, parentId)
245
+ _moveParentToWait(parentPrefix, parentId)
232
246
  end
233
247
  else
234
- moveParentToWait(parentPrefix, parentId, true)
248
+ _moveParentToWait(parentPrefix, parentId, true)
235
249
  end
236
250
  end
237
251
  end
@@ -241,66 +255,86 @@ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debou
241
255
  end
242
256
  return false
243
257
  end
244
- local function removeJob(prefix, jobId, parentKey, removeChildren)
245
- local jobKey = prefix .. jobId;
246
- removeParentDependencyKey(jobKey, false, parentKey, nil)
247
- if removeChildren == "1" then
248
- -- Check if this job has children
249
- -- If so, we are going to try to remove the children recursively in deep first way because
250
- -- if some job is locked we must exit with and error.
251
- -- local countProcessed = rcall("HLEN", jobKey .. ":processed")
258
+ local removeJobChildren
259
+ local removeJobWithChildren
260
+ removeJobChildren = function(prefix, meta, jobKey, options)
261
+ -- Check if this job has children
262
+ -- If so, we are going to try to remove the children recursively in a depth-first way
263
+ -- because if some job is locked, we must exit with an error.
264
+ if not options.ignoreProcessed then
252
265
  local processed = rcall("HGETALL", jobKey .. ":processed")
253
- if (#processed > 0) then
266
+ if #processed > 0 then
254
267
  for i = 1, #processed, 2 do
255
268
  local childJobId = getJobIdFromKey(processed[i])
256
269
  local childJobPrefix = getJobKeyPrefix(processed[i], childJobId)
257
- removeJob(childJobPrefix, childJobId, jobKey, removeChildren)
258
- end
259
- end
260
- local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
261
- if (#dependencies > 0) then
262
- for i, childJobKey in ipairs(dependencies) do
263
- -- We need to get the jobId for this job.
264
- local childJobId = getJobIdFromKey(childJobKey)
265
- local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
266
- removeJob(childJobPrefix, childJobId, jobKey, removeChildren)
270
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
267
271
  end
268
272
  end
269
273
  local failed = rcall("HGETALL", jobKey .. ":failed")
270
- if (#failed > 0) then
274
+ if #failed > 0 then
271
275
  for i = 1, #failed, 2 do
272
276
  local childJobId = getJobIdFromKey(failed[i])
273
277
  local childJobPrefix = getJobKeyPrefix(failed[i], childJobId)
274
- removeJob(childJobPrefix, childJobId, jobKey, removeChildren)
278
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
275
279
  end
276
280
  end
277
281
  local unsuccessful = rcall("ZRANGE", jobKey .. ":unsuccessful", 0, -1)
278
- if (#unsuccessful > 0) then
282
+ if #unsuccessful > 0 then
279
283
  for i = 1, #unsuccessful, 1 do
280
284
  local childJobId = getJobIdFromKey(unsuccessful[i])
281
285
  local childJobPrefix = getJobKeyPrefix(unsuccessful[i], childJobId)
282
- removeJob(childJobPrefix, childJobId, jobKey, removeChildren)
286
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
283
287
  end
284
288
  end
285
289
  end
286
- local prev = removeJobFromAnyState(prefix, jobId)
287
- removeDeduplicationKey(prefix, jobKey)
288
- if removeJobKeys(jobKey) > 0 then
289
- local maxEvents = getOrSetMaxEvents(KEYS[2])
290
- rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed", "jobId", jobId, "prev",
291
- prev)
290
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
291
+ if #dependencies > 0 then
292
+ for i, childJobKey in ipairs(dependencies) do
293
+ local childJobId = getJobIdFromKey(childJobKey)
294
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
295
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
296
+ end
297
+ end
298
+ end
299
+ removeJobWithChildren = function(prefix, meta, jobId, parentKey, options)
300
+ local jobKey = prefix .. jobId
301
+ if options.ignoreLocked then
302
+ if isLocked(prefix, jobId) then
303
+ return
304
+ end
305
+ end
306
+ -- Check if job is in the failed zset
307
+ local failedSet = prefix .. "failed"
308
+ if not (options.ignoreProcessed and rcall("ZSCORE", failedSet, jobId)) then
309
+ removeParentDependencyKey(jobKey, false, parentKey, nil)
310
+ if options.removeChildren then
311
+ removeJobChildren(prefix, meta, jobKey, options)
312
+ end
313
+ local prev = removeJobFromAnyState(prefix, jobId)
314
+ removeDeduplicationKeyIfNeededOnRemoval(prefix, jobKey, jobId)
315
+ if removeJobKeys(jobKey) > 0 then
316
+ local maxEvents = getOrSetMaxEvents(meta)
317
+ rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed",
318
+ "jobId", jobId, "prev", prev)
319
+ end
292
320
  end
293
321
  end
294
- local prefix = KEYS[1]
295
322
  local jobId = ARGV[1]
296
323
  local shouldRemoveChildren = ARGV[2]
297
- local jobKey = prefix .. jobId
324
+ local prefix = ARGV[3]
325
+ local jobKey = KEYS[1]
326
+ local meta = KEYS[2]
298
327
  local repeatKey = KEYS[3]
299
328
  if isJobSchedulerJob(jobId, jobKey, repeatKey) then
300
329
  return -8
301
330
  end
302
331
  if not isLocked(prefix, jobId, shouldRemoveChildren) then
303
- removeJob(prefix, jobId, nil, shouldRemoveChildren)
332
+ local options = {
333
+ removeChildren = shouldRemoveChildren == "1",
334
+ ignoreProcessed = false,
335
+ ignoreLocked = false
336
+ }
337
+ removeJobWithChildren(prefix, meta, jobId, nil, options)
304
338
  return 1
305
339
  end
306
340
  return 0
@@ -1 +1 @@
1
- {"version":3,"file":"removeJob-3.js","sourceRoot":"","sources":["../../../src/scripts/removeJob-3.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkTf,CAAC;AACF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,WAAW;IACjB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
1
+ {"version":3,"file":"removeJob-3.js","sourceRoot":"","sources":["../../../src/scripts/removeJob-3.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoVf,CAAC;AACF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,WAAW;IACjB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const removeUnprocessedChildren: {
2
+ name: string;
3
+ content: string;
4
+ keys: number;
5
+ };
@@ -0,0 +1,335 @@
1
+ const content = `--[[
2
+ Remove a job from all the statuses it may be in as well as all its data.
3
+ In order to be able to remove a job, it cannot be active.
4
+ Input:
5
+ KEYS[1] jobKey
6
+ KEYS[2] meta key
7
+ ARGV[1] prefix
8
+ ARGV[2] jobId
9
+ Events:
10
+ 'removed' for every children removed
11
+ ]]
12
+ -- Includes
13
+ --[[
14
+ Remove a job from all the statuses it may be in as well as all its data,
15
+ including its children. Active children can be ignored.
16
+ Events:
17
+ 'removed'
18
+ ]]
19
+ local rcall = redis.call
20
+ -- Includes
21
+ --[[
22
+ Functions to destructure job key.
23
+ Just a bit of warning, these functions may be a bit slow and affect performance significantly.
24
+ ]]
25
+ local getJobIdFromKey = function (jobKey)
26
+ return string.match(jobKey, ".*:(.*)")
27
+ end
28
+ local getJobKeyPrefix = function (jobKey, jobId)
29
+ return string.sub(jobKey, 0, #jobKey - #jobId)
30
+ end
31
+ --[[
32
+ Function to get max events value or set by default 10000.
33
+ ]]
34
+ local function getOrSetMaxEvents(metaKey)
35
+ local maxEvents = rcall("HGET", metaKey, "opts.maxLenEvents")
36
+ if not maxEvents then
37
+ maxEvents = 10000
38
+ rcall("HSET", metaKey, "opts.maxLenEvents", maxEvents)
39
+ end
40
+ return maxEvents
41
+ end
42
+ --[[
43
+ Function to check if the job belongs to a job scheduler and
44
+ current delayed job matches with jobId
45
+ ]]
46
+ local function isJobSchedulerJob(jobId, jobKey, jobSchedulersKey)
47
+ local repeatJobKey = rcall("HGET", jobKey, "rjk")
48
+ if repeatJobKey then
49
+ local prevMillis = rcall("ZSCORE", jobSchedulersKey, repeatJobKey)
50
+ if prevMillis then
51
+ local currentDelayedJobId = "repeat:" .. repeatJobKey .. ":" .. prevMillis
52
+ return jobId == currentDelayedJobId
53
+ end
54
+ end
55
+ return false
56
+ end
57
+ --[[
58
+ Function to remove deduplication key if needed
59
+ when a job is being removed.
60
+ ]]
61
+ local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
62
+ jobKey, jobId)
63
+ local deduplicationId = rcall("HGET", jobKey, "deid")
64
+ if deduplicationId then
65
+ local deduplicationKey = prefixKey .. "de:" .. deduplicationId
66
+ local currentJobId = rcall('GET', deduplicationKey)
67
+ if currentJobId and currentJobId == jobId then
68
+ return rcall("DEL", deduplicationKey)
69
+ end
70
+ end
71
+ end
72
+ --[[
73
+ Function to remove from any state.
74
+ returns:
75
+ prev state
76
+ ]]
77
+ local function removeJobFromAnyState( prefix, jobId)
78
+ -- We start with the ZSCORE checks, since they have O(1) complexity
79
+ if rcall("ZSCORE", prefix .. "completed", jobId) then
80
+ rcall("ZREM", prefix .. "completed", jobId)
81
+ return "completed"
82
+ elseif rcall("ZSCORE", prefix .. "waiting-children", jobId) then
83
+ rcall("ZREM", prefix .. "waiting-children", jobId)
84
+ return "waiting-children"
85
+ elseif rcall("ZSCORE", prefix .. "delayed", jobId) then
86
+ rcall("ZREM", prefix .. "delayed", jobId)
87
+ return "delayed"
88
+ elseif rcall("ZSCORE", prefix .. "failed", jobId) then
89
+ rcall("ZREM", prefix .. "failed", jobId)
90
+ return "failed"
91
+ elseif rcall("ZSCORE", prefix .. "prioritized", jobId) then
92
+ rcall("ZREM", prefix .. "prioritized", jobId)
93
+ return "prioritized"
94
+ -- We remove only 1 element from the list, since we assume they are not added multiple times
95
+ elseif rcall("LREM", prefix .. "wait", 1, jobId) == 1 then
96
+ return "wait"
97
+ elseif rcall("LREM", prefix .. "paused", 1, jobId) == 1 then
98
+ return "paused"
99
+ elseif rcall("LREM", prefix .. "active", 1, jobId) == 1 then
100
+ return "active"
101
+ end
102
+ return "unknown"
103
+ end
104
+ --[[
105
+ Function to remove job keys.
106
+ ]]
107
+ local function removeJobKeys(jobKey)
108
+ return rcall("DEL", jobKey, jobKey .. ':logs', jobKey .. ':dependencies',
109
+ jobKey .. ':processed', jobKey .. ':failed', jobKey .. ':unsuccessful')
110
+ end
111
+ --[[
112
+ Check if this job has a parent. If so we will just remove it from
113
+ the parent child list, but if it is the last child we should move the parent to "wait/paused"
114
+ which requires code from "moveToFinished"
115
+ ]]
116
+ -- Includes
117
+ --[[
118
+ Function to add job in target list and add marker if needed.
119
+ ]]
120
+ -- Includes
121
+ --[[
122
+ Add marker if needed when a job is available.
123
+ ]]
124
+ local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
125
+ if not isPausedOrMaxed then
126
+ rcall("ZADD", markerKey, 0, "0")
127
+ end
128
+ end
129
+ local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
130
+ rcall(pushCmd, targetKey, jobId)
131
+ addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
132
+ end
133
+ --[[
134
+ Function to check for the meta.paused key to decide if we are paused or not
135
+ (since an empty list and !EXISTS are not really the same).
136
+ ]]
137
+ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
138
+ local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
139
+ if queueAttributes[1] then
140
+ return pausedKey, true
141
+ else
142
+ if queueAttributes[2] then
143
+ local activeCount = rcall("LLEN", activeKey)
144
+ if activeCount >= tonumber(queueAttributes[2]) then
145
+ return waitKey, true
146
+ else
147
+ return waitKey, false
148
+ end
149
+ end
150
+ end
151
+ return waitKey, false
152
+ end
153
+ local function _moveParentToWait(parentPrefix, parentId, emitEvent)
154
+ local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
155
+ parentPrefix .. "wait", parentPrefix .. "paused")
156
+ addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
157
+ if emitEvent then
158
+ local parentEventStream = parentPrefix .. "events"
159
+ rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
160
+ end
161
+ end
162
+ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
163
+ if parentKey then
164
+ local parentDependenciesKey = parentKey .. ":dependencies"
165
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
166
+ if result > 0 then
167
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
168
+ if pendingDependencies == 0 then
169
+ local parentId = getJobIdFromKey(parentKey)
170
+ local parentPrefix = getJobKeyPrefix(parentKey, parentId)
171
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
172
+ if numRemovedElements == 1 then
173
+ if hard then -- remove parent in same queue
174
+ if parentPrefix == baseKey then
175
+ removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
176
+ removeJobKeys(parentKey)
177
+ if debounceId then
178
+ rcall("DEL", parentPrefix .. "de:" .. debounceId)
179
+ end
180
+ else
181
+ _moveParentToWait(parentPrefix, parentId)
182
+ end
183
+ else
184
+ _moveParentToWait(parentPrefix, parentId, true)
185
+ end
186
+ end
187
+ end
188
+ return true
189
+ end
190
+ else
191
+ local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
192
+ local missedParentKey = parentAttributes[1]
193
+ if( (type(missedParentKey) == "string") and missedParentKey ~= ""
194
+ and (rcall("EXISTS", missedParentKey) == 1)) then
195
+ local parentDependenciesKey = missedParentKey .. ":dependencies"
196
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
197
+ if result > 0 then
198
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
199
+ if pendingDependencies == 0 then
200
+ local parentId = getJobIdFromKey(missedParentKey)
201
+ local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
202
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
203
+ if numRemovedElements == 1 then
204
+ if hard then
205
+ if parentPrefix == baseKey then
206
+ removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
207
+ removeJobKeys(missedParentKey)
208
+ if parentAttributes[2] then
209
+ rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
210
+ end
211
+ else
212
+ _moveParentToWait(parentPrefix, parentId)
213
+ end
214
+ else
215
+ _moveParentToWait(parentPrefix, parentId, true)
216
+ end
217
+ end
218
+ end
219
+ return true
220
+ end
221
+ end
222
+ end
223
+ return false
224
+ end
225
+ --[[
226
+ Function to recursively check if there are no locks
227
+ on the jobs to be removed.
228
+ returns:
229
+ boolean
230
+ ]]
231
+ local function isLocked( prefix, jobId, removeChildren)
232
+ local jobKey = prefix .. jobId;
233
+ -- Check if this job is locked
234
+ local lockKey = jobKey .. ':lock'
235
+ local lock = rcall("GET", lockKey)
236
+ if not lock then
237
+ if removeChildren == "1" then
238
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
239
+ if (#dependencies > 0) then
240
+ for i, childJobKey in ipairs(dependencies) do
241
+ -- We need to get the jobId for this job.
242
+ local childJobId = getJobIdFromKey(childJobKey)
243
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
244
+ local result = isLocked( childJobPrefix, childJobId, removeChildren )
245
+ if result then
246
+ return true
247
+ end
248
+ end
249
+ end
250
+ end
251
+ return false
252
+ end
253
+ return true
254
+ end
255
+ local removeJobChildren
256
+ local removeJobWithChildren
257
+ removeJobChildren = function(prefix, meta, jobKey, options)
258
+ -- Check if this job has children
259
+ -- If so, we are going to try to remove the children recursively in a depth-first way
260
+ -- because if some job is locked, we must exit with an error.
261
+ if not options.ignoreProcessed then
262
+ local processed = rcall("HGETALL", jobKey .. ":processed")
263
+ if #processed > 0 then
264
+ for i = 1, #processed, 2 do
265
+ local childJobId = getJobIdFromKey(processed[i])
266
+ local childJobPrefix = getJobKeyPrefix(processed[i], childJobId)
267
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
268
+ end
269
+ end
270
+ local failed = rcall("HGETALL", jobKey .. ":failed")
271
+ if #failed > 0 then
272
+ for i = 1, #failed, 2 do
273
+ local childJobId = getJobIdFromKey(failed[i])
274
+ local childJobPrefix = getJobKeyPrefix(failed[i], childJobId)
275
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
276
+ end
277
+ end
278
+ local unsuccessful = rcall("ZRANGE", jobKey .. ":unsuccessful", 0, -1)
279
+ if #unsuccessful > 0 then
280
+ for i = 1, #unsuccessful, 1 do
281
+ local childJobId = getJobIdFromKey(unsuccessful[i])
282
+ local childJobPrefix = getJobKeyPrefix(unsuccessful[i], childJobId)
283
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
284
+ end
285
+ end
286
+ end
287
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
288
+ if #dependencies > 0 then
289
+ for i, childJobKey in ipairs(dependencies) do
290
+ local childJobId = getJobIdFromKey(childJobKey)
291
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
292
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
293
+ end
294
+ end
295
+ end
296
+ removeJobWithChildren = function(prefix, meta, jobId, parentKey, options)
297
+ local jobKey = prefix .. jobId
298
+ if options.ignoreLocked then
299
+ if isLocked(prefix, jobId) then
300
+ return
301
+ end
302
+ end
303
+ -- Check if job is in the failed zset
304
+ local failedSet = prefix .. "failed"
305
+ if not (options.ignoreProcessed and rcall("ZSCORE", failedSet, jobId)) then
306
+ removeParentDependencyKey(jobKey, false, parentKey, nil)
307
+ if options.removeChildren then
308
+ removeJobChildren(prefix, meta, jobKey, options)
309
+ end
310
+ local prev = removeJobFromAnyState(prefix, jobId)
311
+ removeDeduplicationKeyIfNeededOnRemoval(prefix, jobKey, jobId)
312
+ if removeJobKeys(jobKey) > 0 then
313
+ local maxEvents = getOrSetMaxEvents(meta)
314
+ rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed",
315
+ "jobId", jobId, "prev", prev)
316
+ end
317
+ end
318
+ end
319
+ local prefix = ARGV[1]
320
+ local jobId = ARGV[2]
321
+ local jobKey = KEYS[1]
322
+ local metaKey = KEYS[2]
323
+ local options = {
324
+ removeChildren = "1",
325
+ ignoreProcessed = true,
326
+ ignoreLocked = true
327
+ }
328
+ removeJobChildren(prefix, metaKey, jobKey, options)
329
+ `;
330
+ export const removeUnprocessedChildren = {
331
+ name: 'removeUnprocessedChildren',
332
+ content,
333
+ keys: 2,
334
+ };
335
+ //# sourceMappingURL=removeUnprocessedChildren-2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeUnprocessedChildren-2.js","sourceRoot":"","sources":["../../../src/scripts/removeUnprocessedChildren-2.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwUf,CAAC;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,2BAA2B;IACjC,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
@@ -22,7 +22,8 @@ const content = `--[[
22
22
  ARGV[7] producer id
23
23
  Output:
24
24
  next delayed job id - OK
25
- ]] local rcall = redis.call
25
+ ]]
26
+ local rcall = redis.call
26
27
  local repeatKey = KEYS[1]
27
28
  local delayedKey = KEYS[2]
28
29
  local waitKey = KEYS[3]
@@ -151,7 +152,7 @@ local function storeJob(eventsKey, jobIdKey, jobId, name, data, opts, timestamp,
151
152
  table.insert(optionalValues, "parent")
152
153
  table.insert(optionalValues, parentData)
153
154
  end
154
- if repeatJobKey ~= nil then
155
+ if repeatJobKey then
155
156
  table.insert(optionalValues, "rjk")
156
157
  table.insert(optionalValues, repeatJobKey)
157
158
  end
@@ -231,29 +232,34 @@ local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
231
232
  local nextDelayedJobKey = schedulerKey .. ":" .. nextMillis
232
233
  -- Validate that scheduler exists.
233
234
  local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
234
- if prevMillis ~= false then
235
+ if prevMillis then
235
236
  local currentDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
236
- if producerId == currentDelayedJobId and rcall("EXISTS", nextDelayedJobKey) ~= 1 then
237
- local schedulerAttributes = rcall("HMGET", schedulerKey, "name", "data")
238
- rcall("ZADD", repeatKey, nextMillis, jobSchedulerId)
239
- rcall("HINCRBY", schedulerKey, "ic", 1)
237
+ if producerId == currentDelayedJobId then
240
238
  local eventsKey = KEYS[9]
241
239
  local maxEvents = getOrSetMaxEvents(metaKey)
242
- rcall("INCR", KEYS[8])
243
- -- TODO: remove this workaround in next breaking change,
244
- -- all job-schedulers must save job data
245
- local templateData = schedulerAttributes[2] or ARGV[3]
246
- if templateData and templateData ~= '{}' then
247
- rcall("HSET", schedulerKey, "data", templateData)
248
- end
249
- addJobFromScheduler(nextDelayedJobKey, nextDelayedJobId, ARGV[4], waitKey, pausedKey,
250
- KEYS[12], metaKey, prioritizedKey, KEYS[10], delayedKey, KEYS[7], eventsKey,
251
- schedulerAttributes[1], maxEvents, ARGV[5], templateData or '{}', jobSchedulerId)
252
- -- TODO: remove this workaround in next breaking change
253
- if KEYS[11] ~= "" then
254
- rcall("HSET", KEYS[11], "nrjid", nextDelayedJobId)
240
+ if rcall("EXISTS", nextDelayedJobKey) ~= 1 then
241
+ local schedulerAttributes = rcall("HMGET", schedulerKey, "name", "data")
242
+ rcall("ZADD", repeatKey, nextMillis, jobSchedulerId)
243
+ rcall("HINCRBY", schedulerKey, "ic", 1)
244
+ rcall("INCR", KEYS[8])
245
+ -- TODO: remove this workaround in next breaking change,
246
+ -- all job-schedulers must save job data
247
+ local templateData = schedulerAttributes[2] or ARGV[3]
248
+ if templateData and templateData ~= '{}' then
249
+ rcall("HSET", schedulerKey, "data", templateData)
250
+ end
251
+ addJobFromScheduler(nextDelayedJobKey, nextDelayedJobId, ARGV[4], waitKey, pausedKey,
252
+ KEYS[12], metaKey, prioritizedKey, KEYS[10], delayedKey, KEYS[7], eventsKey,
253
+ schedulerAttributes[1], maxEvents, ARGV[5], templateData or '{}', jobSchedulerId)
254
+ -- TODO: remove this workaround in next breaking change
255
+ if KEYS[11] ~= "" then
256
+ rcall("HSET", KEYS[11], "nrjid", nextDelayedJobId)
257
+ end
258
+ return nextDelayedJobId .. "" -- convert to string
259
+ else
260
+ rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event",
261
+ "duplicated", "jobId", nextDelayedJobId)
255
262
  end
256
- return nextDelayedJobId .. "" -- convert to string
257
263
  end
258
264
  end
259
265
  `;