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