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
@@ -0,0 +1,48 @@
1
+ --[[
2
+ Move parent to a wait status (wait, prioritized or delayed)
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "addDelayMarkerIfNeeded"
7
+ --- @include "addJobInTargetList"
8
+ --- @include "addJobWithPriority"
9
+ --- @include "isQueuePausedOrMaxed"
10
+ --- @include "getTargetQueueList"
11
+ local function moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
12
+ local parentWaitKey = parentQueueKey .. ":wait"
13
+ local parentPausedKey = parentQueueKey .. ":paused"
14
+ local parentActiveKey = parentQueueKey .. ":active"
15
+ local parentMetaKey = parentQueueKey .. ":meta"
16
+
17
+ local parentMarkerKey = parentQueueKey .. ":marker"
18
+ local jobAttributes = rcall("HMGET", parentKey, "priority", "delay")
19
+ local priority = tonumber(jobAttributes[1]) or 0
20
+ local delay = tonumber(jobAttributes[2]) or 0
21
+
22
+ -- ignore dependencies if any left
23
+ rcall("HSET", parentKey, "igdp", 1)
24
+
25
+ if delay > 0 then
26
+ local delayedTimestamp = tonumber(timestamp) + delay
27
+ local score = delayedTimestamp * 0x1000
28
+ local parentDelayedKey = parentQueueKey .. ":delayed"
29
+ rcall("ZADD", parentDelayedKey, score, parentId)
30
+ rcall("XADD", parentQueueKey .. ":events", "*", "event", "delayed", "jobId", parentId, "delay",
31
+ delayedTimestamp)
32
+
33
+ addDelayMarkerIfNeeded(parentMarkerKey, parentDelayedKey)
34
+ else
35
+ if priority == 0 then
36
+ local parentTarget, isParentPausedOrMaxed = getTargetQueueList(parentMetaKey, parentActiveKey,
37
+ parentWaitKey, parentPausedKey)
38
+ addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed, parentId)
39
+ else
40
+ local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
41
+ addJobWithPriority(parentMarkerKey, parentQueueKey .. ":prioritized", priority, parentId,
42
+ parentQueueKey .. ":pc", isPausedOrMaxed)
43
+ end
44
+
45
+ rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev",
46
+ "waiting-children")
47
+ end
48
+ end
@@ -1,55 +1,14 @@
1
1
  --[[
2
- Validate and move parent to active if needed.
2
+ Validate and move parent to a wait status (waiting, delayed or prioritized) if needed.
3
3
  ]]
4
-
5
4
  -- Includes
6
- --- @include "addDelayMarkerIfNeeded"
7
- --- @include "addJobInTargetList"
8
- --- @include "addJobWithPriority"
9
- --- @include "isQueuePausedOrMaxed"
10
- --- @include "getTargetQueueList"
11
-
12
- local function moveParentToWaitIfNeeded(parentQueueKey, parentDependenciesKey,
13
- parentKey, parentId, timestamp)
14
- local isParentActive = rcall("ZSCORE",
15
- parentQueueKey .. ":waiting-children", parentId)
16
- if rcall("SCARD", parentDependenciesKey) == 0 and isParentActive then
17
- rcall("ZREM", parentQueueKey .. ":waiting-children", parentId)
18
- local parentWaitKey = parentQueueKey .. ":wait"
19
- local parentPausedKey = parentQueueKey .. ":paused"
20
- local parentActiveKey = parentQueueKey .. ":active"
21
- local parentMetaKey = parentQueueKey .. ":meta"
22
-
23
- local parentMarkerKey = parentQueueKey .. ":marker"
24
- local jobAttributes = rcall("HMGET", parentKey, "priority", "delay")
25
- local priority = tonumber(jobAttributes[1]) or 0
26
- local delay = tonumber(jobAttributes[2]) or 0
27
-
28
- if delay > 0 then
29
- local delayedTimestamp = tonumber(timestamp) + delay
30
- local score = delayedTimestamp * 0x1000
31
- local parentDelayedKey = parentQueueKey .. ":delayed"
32
- rcall("ZADD", parentDelayedKey, score, parentId)
33
- rcall("XADD", parentQueueKey .. ":events", "*", "event", "delayed",
34
- "jobId", parentId, "delay", delayedTimestamp)
35
-
36
- addDelayMarkerIfNeeded(parentMarkerKey, parentDelayedKey)
37
- else
38
- if priority == 0 then
39
- local parentTarget, isParentPausedOrMaxed =
40
- getTargetQueueList(parentMetaKey, parentActiveKey, parentWaitKey,
41
- parentPausedKey)
42
- addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed,
43
- parentId)
44
- else
45
- local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
46
- addJobWithPriority(parentMarkerKey,
47
- parentQueueKey .. ":prioritized", priority,
48
- parentId, parentQueueKey .. ":pc", isPausedOrMaxed)
49
- end
50
-
51
- rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting",
52
- "jobId", parentId, "prev", "waiting-children")
53
- end
5
+ --- @include "moveParentToWait"
6
+ local function moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
7
+ if rcall("EXISTS", parentKey) == 1 then
8
+ local parentWaitingChildrenKey = parentQueueKey .. ":waiting-children"
9
+ if rcall("ZSCORE", parentWaitingChildrenKey, parentId) then
10
+ rcall("ZREM", parentWaitingChildrenKey, parentId)
11
+ moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
54
12
  end
13
+ end
55
14
  end
@@ -0,0 +1,13 @@
1
+ --[[
2
+ Validate and move parent to a wait status (waiting, delayed or prioritized)
3
+ if no pending dependencies.
4
+ ]]
5
+ -- Includes
6
+ --- @include "moveParentToWaitIfNeeded"
7
+ local function moveParentToWaitIfNoPendingDependencies(parentQueueKey, parentDependenciesKey, parentKey,
8
+ parentId, timestamp)
9
+ local doNotHavePendingDependencies = rcall("SCARD", parentDependenciesKey) == 0
10
+ if doNotHavePendingDependencies then
11
+ moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ --[[
2
+ Function to remove deduplication key if needed
3
+ when a job is moved to completed or failed states.
4
+ ]]
5
+
6
+ local function removeDeduplicationKeyIfNeededOnFinalization(prefixKey,
7
+ deduplicationId, jobId)
8
+ if deduplicationId then
9
+ local deduplicationKey = prefixKey .. "de:" .. deduplicationId
10
+ local pttl = rcall("PTTL", deduplicationKey)
11
+
12
+ if pttl == 0 then
13
+ return rcall("DEL", deduplicationKey)
14
+ end
15
+
16
+ if pttl == -1 then
17
+ local currentJobId = rcall('GET', deduplicationKey)
18
+ if currentJobId and currentJobId == jobId then
19
+ return rcall("DEL", deduplicationKey)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ --[[
2
+ Function to remove deduplication key if needed
3
+ when a job is being removed.
4
+ ]]
5
+
6
+ local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
7
+ jobKey, jobId)
8
+ local deduplicationId = rcall("HGET", jobKey, "deid")
9
+ if deduplicationId then
10
+ local deduplicationKey = prefixKey .. "de:" .. deduplicationId
11
+ local currentJobId = rcall('GET', deduplicationKey)
12
+ if currentJobId and currentJobId == jobId then
13
+ return rcall("DEL", deduplicationKey)
14
+ end
15
+ end
16
+ end
@@ -3,7 +3,7 @@
3
3
  ]]
4
4
 
5
5
  -- Includes
6
- --- @include "removeDeduplicationKey"
6
+ --- @include "removeDeduplicationKeyIfNeededOnRemoval"
7
7
  --- @include "removeJobKeys"
8
8
  --- @include "removeParentDependencyKey"
9
9
 
@@ -11,7 +11,7 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
11
11
  local jobKey = baseKey .. jobId
12
12
  removeParentDependencyKey(jobKey, hard, nil, baseKey)
13
13
  if shouldRemoveDeduplicationKey then
14
- removeDeduplicationKey(baseKey, jobKey)
14
+ removeDeduplicationKeyIfNeededOnRemoval(baseKey, jobKey, jobId)
15
15
  end
16
16
  removeJobKeys(jobKey)
17
17
  end
@@ -0,0 +1,94 @@
1
+ --[[
2
+ Remove a job from all the statuses it may be in as well as all its data,
3
+ including its children. Active children can be ignored.
4
+
5
+ Events:
6
+ 'removed'
7
+ ]]
8
+
9
+ local rcall = redis.call
10
+
11
+ -- Includes
12
+ --- @include "destructureJobKey"
13
+ --- @include "getOrSetMaxEvents"
14
+ --- @include "isJobSchedulerJob"
15
+ --- @include "removeDeduplicationKeyIfNeededOnRemoval"
16
+ --- @include "removeJobFromAnyState"
17
+ --- @include "removeJobKeys"
18
+ --- @include "removeParentDependencyKey"
19
+ --- @include "isLocked"
20
+
21
+ local removeJobChildren
22
+ local removeJobWithChildren
23
+
24
+ removeJobChildren = function(prefix, meta, jobKey, options)
25
+ -- Check if this job has children
26
+ -- If so, we are going to try to remove the children recursively in a depth-first way
27
+ -- because if some job is locked, we must exit with an error.
28
+
29
+ if not options.ignoreProcessed then
30
+ local processed = rcall("HGETALL", jobKey .. ":processed")
31
+ if #processed > 0 then
32
+ for i = 1, #processed, 2 do
33
+ local childJobId = getJobIdFromKey(processed[i])
34
+ local childJobPrefix = getJobKeyPrefix(processed[i], childJobId)
35
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
36
+ end
37
+ end
38
+
39
+ local failed = rcall("HGETALL", jobKey .. ":failed")
40
+ if #failed > 0 then
41
+ for i = 1, #failed, 2 do
42
+ local childJobId = getJobIdFromKey(failed[i])
43
+ local childJobPrefix = getJobKeyPrefix(failed[i], childJobId)
44
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
45
+ end
46
+ end
47
+
48
+ local unsuccessful = rcall("ZRANGE", jobKey .. ":unsuccessful", 0, -1)
49
+ if #unsuccessful > 0 then
50
+ for i = 1, #unsuccessful, 1 do
51
+ local childJobId = getJobIdFromKey(unsuccessful[i])
52
+ local childJobPrefix = getJobKeyPrefix(unsuccessful[i], childJobId)
53
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
54
+ end
55
+ end
56
+ end
57
+
58
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
59
+ if #dependencies > 0 then
60
+ for i, childJobKey in ipairs(dependencies) do
61
+ local childJobId = getJobIdFromKey(childJobKey)
62
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
63
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
64
+ end
65
+ end
66
+ end
67
+
68
+ removeJobWithChildren = function(prefix, meta, jobId, parentKey, options)
69
+ local jobKey = prefix .. jobId
70
+
71
+ if options.ignoreLocked then
72
+ if isLocked(prefix, jobId) then
73
+ return
74
+ end
75
+ end
76
+
77
+ -- Check if job is in the failed zset
78
+ local failedSet = prefix .. "failed"
79
+ if not (options.ignoreProcessed and rcall("ZSCORE", failedSet, jobId)) then
80
+ removeParentDependencyKey(jobKey, false, parentKey, nil)
81
+
82
+ if options.removeChildren then
83
+ removeJobChildren(prefix, meta, jobKey, options)
84
+ end
85
+
86
+ local prev = removeJobFromAnyState(prefix, jobId)
87
+ removeDeduplicationKeyIfNeededOnRemoval(prefix, jobKey, jobId)
88
+ if removeJobKeys(jobKey) > 0 then
89
+ local maxEvents = getOrSetMaxEvents(meta)
90
+ rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed",
91
+ "jobId", jobId, "prev", prev)
92
+ end
93
+ end
94
+ end
@@ -10,7 +10,7 @@
10
10
  --- @include "getTargetQueueList"
11
11
  --- @include "removeJobKeys"
12
12
 
13
- local function moveParentToWait(parentPrefix, parentId, emitEvent)
13
+ local function _moveParentToWait(parentPrefix, parentId, emitEvent)
14
14
  local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
15
15
  parentPrefix .. "wait", parentPrefix .. "paused")
16
16
  addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
@@ -42,10 +42,10 @@ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debou
42
42
  rcall("DEL", parentPrefix .. "de:" .. debounceId)
43
43
  end
44
44
  else
45
- moveParentToWait(parentPrefix, parentId)
45
+ _moveParentToWait(parentPrefix, parentId)
46
46
  end
47
47
  else
48
- moveParentToWait(parentPrefix, parentId, true)
48
+ _moveParentToWait(parentPrefix, parentId, true)
49
49
  end
50
50
  end
51
51
  end
@@ -75,10 +75,10 @@ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debou
75
75
  rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
76
76
  end
77
77
  else
78
- moveParentToWait(parentPrefix, parentId)
78
+ _moveParentToWait(parentPrefix, parentId)
79
79
  end
80
80
  else
81
- moveParentToWait(parentPrefix, parentId, true)
81
+ _moveParentToWait(parentPrefix, parentId, true)
82
82
  end
83
83
  end
84
84
  end
@@ -16,7 +16,7 @@ local function storeJob(eventsKey, jobIdKey, jobId, name, data, opts, timestamp,
16
16
  table.insert(optionalValues, parentData)
17
17
  end
18
18
 
19
- if repeatJobKey ~= nil then
19
+ if repeatJobKey then
20
20
  table.insert(optionalValues, "rjk")
21
21
  table.insert(optionalValues, repeatJobKey)
22
22
  end
@@ -3,11 +3,11 @@
3
3
  ]]
4
4
 
5
5
  -- Includes
6
- --- @include "moveParentToWaitIfNeeded"
6
+ --- @include "moveParentToWaitIfNoPendingDependencies"
7
7
 
8
8
  local function updateParentDepsIfNeeded(parentKey, parentQueueKey, parentDependenciesKey,
9
9
  parentId, jobIdKey, returnvalue, timestamp )
10
10
  local processedSet = parentKey .. ":processed"
11
11
  rcall("HSET", processedSet, jobIdKey, returnvalue)
12
- moveParentToWaitIfNeeded(parentQueueKey, parentDependenciesKey, parentKey, parentId, timestamp)
12
+ moveParentToWaitIfNoPendingDependencies(parentQueueKey, parentDependenciesKey, parentKey, parentId, timestamp)
13
13
  end
@@ -20,16 +20,14 @@
20
20
  Events:
21
21
  'stalled' with stalled job id.
22
22
  ]]
23
-
24
23
  local rcall = redis.call
25
24
 
26
25
  -- Includes
27
26
  --- @include "includes/addJobInTargetList"
28
27
  --- @include "includes/batches"
29
28
  --- @include "includes/getTargetQueueList"
30
- --- @include "includes/moveParentFromWaitingChildrenToFailed"
31
- --- @include "includes/moveParentToWaitIfNeeded"
32
- --- @include "includes/removeDeduplicationKeyIfNeeded"
29
+ --- @include "includes/moveChildFromDependenciesIfNeeded"
30
+ --- @include "includes/removeDeduplicationKeyIfNeededOnFinalization"
33
31
  --- @include "includes/removeJobsOnFail"
34
32
  --- @include "includes/trimEvents"
35
33
 
@@ -47,7 +45,9 @@ local queueKeyPrefix = ARGV[2]
47
45
  local timestamp = ARGV[3]
48
46
  local maxCheckTime = ARGV[4]
49
47
 
50
- if rcall("EXISTS", stalledCheckKey) == 1 then return {{}, {}} end
48
+ if rcall("EXISTS", stalledCheckKey) == 1 then
49
+ return {{}, {}}
50
+ end
51
51
 
52
52
  rcall("SET", stalledCheckKey, timestamp, "PX", maxCheckTime)
53
53
 
@@ -77,70 +77,35 @@ if (#stalling > 0) then
77
77
 
78
78
  if (removed > 0) then
79
79
  -- If this job has been stalled too many times, such as if it crashes the worker, then fail it.
80
- local stalledCount =
81
- rcall("HINCRBY", jobKey, "stalledCounter", 1)
80
+ local stalledCount = rcall("HINCRBY", jobKey, "stc", 1)
82
81
  if (stalledCount > maxStalledJobCount) then
83
82
  local jobAttributes = rcall("HMGET", jobKey, "opts", "parent", "deid")
84
83
  local rawOpts = jobAttributes[1]
85
84
  local rawParentData = jobAttributes[2]
86
85
  local opts = cjson.decode(rawOpts)
87
86
  rcall("ZADD", failedKey, timestamp, jobId)
88
- removeDeduplicationKeyIfNeeded(queueKeyPrefix, jobAttributes[3])
89
-
90
- local failedReason =
91
- "job stalled more than allowable limit"
92
- rcall("HMSET", jobKey, "failedReason", failedReason,
93
- "finishedOn", timestamp)
94
- rcall("XADD", eventStreamKey, "*", "event",
95
- "failed", "jobId", jobId, 'prev', 'active',
96
- 'failedReason', failedReason)
97
-
98
- if rawParentData then
99
- if opts['fpof'] then
100
- local parentData = cjson.decode(rawParentData)
101
- -- TODO: need to remove this job from dependencies set in next breaking change
102
- -- no for now as it would imply a breaking change
103
- local parentKey = parentData['queueKey'] .. ':' .. parentData['id']
104
- local unsuccesssfulSet = parentKey .. ":unsuccessful"
105
- rcall("ZADD", unsuccesssfulSet, timestamp, jobKey)
106
- moveParentFromWaitingChildrenToFailed(
107
- parentData['queueKey'],
108
- parentData['queueKey'] .. ':' .. parentData['id'],
109
- parentData['id'],
110
- jobKey,
111
- timestamp
112
- )
113
- elseif opts['idof'] or opts['rdof'] then
114
- local parentData = cjson.decode(rawParentData)
115
- local parentKey = parentData['queueKey'] .. ':' .. parentData['id']
116
- local dependenciesSet = parentKey .. ":dependencies"
117
- if rcall("SREM", dependenciesSet, jobKey) == 1 then
118
- moveParentToWaitIfNeeded(parentData['queueKey'], dependenciesSet,
119
- parentKey, parentData['id'], timestamp)
120
- if opts['idof'] then
121
- local failedSet = parentKey .. ":failed"
122
- rcall("HSET", failedSet, jobKey, failedReason)
123
- end
124
- end
125
- end
126
- end
87
+ removeDeduplicationKeyIfNeededOnFinalization(queueKeyPrefix, jobAttributes[3], jobId)
88
+
89
+ local failedReason = "job stalled more than allowable limit"
90
+ rcall("HMSET", jobKey, "failedReason", failedReason, "finishedOn", timestamp)
91
+ rcall("XADD", eventStreamKey, "*", "event", "failed", "jobId", jobId, 'prev', 'active',
92
+ 'failedReason', failedReason)
93
+
94
+ moveChildFromDependenciesIfNeeded(rawParentData, jobKey, failedReason, timestamp)
127
95
 
128
96
  removeJobsOnFail(queueKeyPrefix, failedKey, jobId, opts, timestamp)
129
97
 
130
98
  table.insert(failed, jobId)
131
99
  else
132
- local target, isPausedOrMaxed =
133
- getTargetQueueList(metaKey, activeKey, waitKey, pausedKey)
100
+ local target, isPausedOrMaxed = getTargetQueueList(metaKey, activeKey, waitKey, pausedKey)
134
101
 
135
102
  -- Move the job back to the wait queue, to immediately be picked up by a waiting worker.
136
103
  addJobInTargetList(target, markerKey, "RPUSH", isPausedOrMaxed, jobId)
137
104
 
138
- rcall("XADD", eventStreamKey, "*", "event",
139
- "waiting", "jobId", jobId, 'prev', 'active')
105
+ rcall("XADD", eventStreamKey, "*", "event", "waiting", "jobId", jobId, 'prev', 'active')
140
106
 
141
107
  -- Emit the stalled event
142
- rcall("XADD", eventStreamKey, "*", "event",
143
- "stalled", "jobId", jobId)
108
+ rcall("XADD", eventStreamKey, "*", "event", "stalled", "jobId", jobId)
144
109
  table.insert(stalled, jobId)
145
110
  end
146
111
  end
@@ -158,4 +123,4 @@ if (#active > 0) then
158
123
  end
159
124
  end
160
125
 
161
- return {failed, stalled}
126
+ return {failed, stalled}
@@ -40,6 +40,7 @@
40
40
  opts - attempts max attempts
41
41
  opts - maxMetricsSize
42
42
  opts - fpof - fail parent on fail
43
+ opts - cpof - continue parent on fail
43
44
  opts - idof - ignore dependency on fail
44
45
  opts - rdof - remove dependency on fail
45
46
  opts - name - worker name
@@ -63,11 +64,10 @@ local rcall = redis.call
63
64
  --- @include "includes/getRateLimitTTL"
64
65
  --- @include "includes/getTargetQueueList"
65
66
  --- @include "includes/moveJobFromPriorityToActive"
66
- --- @include "includes/moveParentFromWaitingChildrenToFailed"
67
- --- @include "includes/moveParentToWaitIfNeeded"
67
+ --- @include "includes/moveChildFromDependenciesIfNeeded"
68
68
  --- @include "includes/prepareJobForProcessing"
69
69
  --- @include "includes/promoteDelayedJobs"
70
- --- @include "includes/removeDeduplicationKeyIfNeeded"
70
+ --- @include "includes/removeDeduplicationKeyIfNeededOnFinalization"
71
71
  --- @include "includes/removeJobKeys"
72
72
  --- @include "includes/removeJobsByMaxAge"
73
73
  --- @include "includes/removeJobsByMaxCount"
@@ -78,7 +78,15 @@ local rcall = redis.call
78
78
  --- @include "includes/updateJobFields"
79
79
 
80
80
  local jobIdKey = KEYS[12]
81
- if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
81
+ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
82
+ -- Make sure it does not have pending dependencies
83
+ -- It must happen before removing lock
84
+ if ARGV[5] == "completed" and
85
+ not rcall("HGET", jobIdKey, "igdp") and -- check if we should ignore this check
86
+ rcall("SCARD", jobIdKey .. ":dependencies") ~= 0 then
87
+ return -4
88
+ end
89
+
82
90
  local opts = cmsgpack.unpack(ARGV[8])
83
91
 
84
92
  local token = opts['token']
@@ -95,15 +103,11 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
95
103
  local maxCount = opts['keepJobs']['count']
96
104
  local maxAge = opts['keepJobs']['age']
97
105
 
98
- if rcall("SCARD", jobIdKey .. ":dependencies") ~= 0 then -- // Make sure it does not have pending dependencies
99
- return -4
100
- end
101
-
102
106
  local jobAttributes = rcall("HMGET", jobIdKey, "parentKey", "parent", "deid")
103
107
  local parentKey = jobAttributes[1] or ""
104
108
  local parentId = ""
105
109
  local parentQueueKey = ""
106
- if jobAttributes[2] then
110
+ if jobAttributes[2] then -- TODO: need to revisit this logic if it's still needed
107
111
  local jsonDecodedParent = cjson.decode(jobAttributes[2])
108
112
  parentId = jsonDecodedParent['id']
109
113
  parentQueueKey = jsonDecodedParent['queueKey']
@@ -115,7 +119,9 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
115
119
  -- Remove from active list (if not active we shall return error)
116
120
  local numRemovedElements = rcall("LREM", KEYS[2], -1, jobId)
117
121
 
118
- if (numRemovedElements < 1) then return -3 end
122
+ if (numRemovedElements < 1) then
123
+ return -3
124
+ end
119
125
 
120
126
  local eventStreamKey = KEYS[4]
121
127
  local metaKey = KEYS[9]
@@ -124,7 +130,7 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
124
130
 
125
131
  local prefix = ARGV[7]
126
132
 
127
- removeDeduplicationKeyIfNeeded(prefix, jobAttributes[3])
133
+ removeDeduplicationKeyIfNeededOnFinalization(prefix, jobAttributes[3], jobId)
128
134
 
129
135
  -- If job has a parent we need to
130
136
  -- 1) remove this job id from parents dependencies
@@ -140,28 +146,11 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
140
146
  if ARGV[5] == "completed" then
141
147
  local dependenciesSet = parentKey .. ":dependencies"
142
148
  if rcall("SREM", dependenciesSet, jobIdKey) == 1 then
143
- updateParentDepsIfNeeded(parentKey, parentQueueKey,
144
- dependenciesSet, parentId, jobIdKey,
145
- ARGV[4], timestamp)
149
+ updateParentDepsIfNeeded(parentKey, parentQueueKey, dependenciesSet, parentId, jobIdKey, ARGV[4],
150
+ timestamp)
146
151
  end
147
152
  else
148
- if opts['fpof'] then
149
- local unsuccesssfulSet = parentKey .. ":unsuccessful"
150
- rcall("ZADD", unsuccesssfulSet, timestamp, jobIdKey)
151
- moveParentFromWaitingChildrenToFailed(parentQueueKey, parentKey,
152
- parentId, jobIdKey,
153
- timestamp)
154
- elseif opts['idof'] or opts['rdof'] then
155
- local dependenciesSet = parentKey .. ":dependencies"
156
- if rcall("SREM", dependenciesSet, jobIdKey) == 1 then
157
- moveParentToWaitIfNeeded(parentQueueKey, dependenciesSet,
158
- parentKey, parentId, timestamp)
159
- if opts['idof'] then
160
- local failedSet = parentKey .. ":failed"
161
- rcall("HSET", failedSet, jobIdKey, ARGV[4])
162
- end
163
- end
164
- end
153
+ moveChildFromDependenciesIfNeeded(jobAttributes[2], jobIdKey, ARGV[4], timestamp)
165
154
  end
166
155
  end
167
156
 
@@ -172,9 +161,13 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
172
161
  local targetSet = KEYS[11]
173
162
  -- Add to complete/failed set
174
163
  rcall("ZADD", targetSet, timestamp, jobId)
175
- rcall("HMSET", jobIdKey, ARGV[3], ARGV[4], "finishedOn", timestamp)
164
+ rcall("HSET", jobIdKey, ARGV[3], ARGV[4], "finishedOn", timestamp)
176
165
  -- "returnvalue" / "failedReason" and "finishedOn"
177
166
 
167
+ if ARGV[5] == "failed" then
168
+ rcall("HDEL", jobIdKey, "defa")
169
+ end
170
+
178
171
  -- Remove old jobs?
179
172
  if maxAge ~= nil then
180
173
  removeJobsByMaxAge(timestamp, maxAge, targetSet, prefix)
@@ -193,13 +186,12 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
193
186
  end
194
187
  end
195
188
 
196
- rcall("XADD", eventStreamKey, "*", "event", ARGV[5], "jobId", jobId, ARGV[3],
197
- ARGV[4])
189
+ rcall("XADD", eventStreamKey, "*", "event", ARGV[5], "jobId", jobId, ARGV[3], ARGV[4], "prev", "active")
198
190
 
199
191
  if ARGV[5] == "failed" then
200
192
  if tonumber(attemptsMade) >= tonumber(attempts) then
201
- rcall("XADD", eventStreamKey, "*", "event", "retries-exhausted", "jobId",
202
- jobId, "attemptsMade", attemptsMade)
193
+ rcall("XADD", eventStreamKey, "*", "event", "retries-exhausted", "jobId", jobId, "attemptsMade",
194
+ attemptsMade)
203
195
  end
204
196
  end
205
197
 
@@ -216,17 +208,21 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
216
208
 
217
209
  local markerKey = KEYS[14]
218
210
  -- Check if there are delayed jobs that can be promoted
219
- promoteDelayedJobs(KEYS[7], markerKey, target, KEYS[3], eventStreamKey, prefix,
220
- timestamp, KEYS[10], isPausedOrMaxed)
211
+ promoteDelayedJobs(KEYS[7], markerKey, target, KEYS[3], eventStreamKey, prefix, timestamp, KEYS[10],
212
+ isPausedOrMaxed)
221
213
 
222
214
  local maxJobs = tonumber(opts['limiter'] and opts['limiter']['max'])
223
215
  -- Check if we are rate limited first.
224
216
  local expireTime = getRateLimitTTL(maxJobs, KEYS[6])
225
217
 
226
- if expireTime > 0 then return {0, 0, expireTime, 0} end
218
+ if expireTime > 0 then
219
+ return {0, 0, expireTime, 0}
220
+ end
227
221
 
228
222
  -- paused or maxed queue
229
- if isPausedOrMaxed then return {0, 0, 0, 0} end
223
+ if isPausedOrMaxed then
224
+ return {0, 0, 0, 0}
225
+ end
230
226
 
231
227
  jobId = rcall("RPOPLPUSH", KEYS[1], KEYS[2])
232
228
 
@@ -238,23 +234,19 @@ if rcall("EXISTS", jobIdKey) == 1 then -- // Make sure job exists
238
234
  -- If jobId is special ID 0:delay (delay greater than 0), then there is no job to process
239
235
  -- but if ID is 0:0, then there is at least 1 prioritized job to process
240
236
  if jobId == "0:0" then
241
- jobId = moveJobFromPriorityToActive(KEYS[3], KEYS[2],
242
- KEYS[10])
243
- return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId,
244
- timestamp, maxJobs, markerKey,
245
- opts)
237
+ jobId = moveJobFromPriorityToActive(KEYS[3], KEYS[2], KEYS[10])
238
+ return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
239
+ markerKey, opts)
246
240
  end
247
241
  else
248
- return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId,
249
- timestamp, maxJobs, markerKey,
250
- opts)
242
+ return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs, markerKey,
243
+ opts)
251
244
  end
252
245
  else
253
246
  jobId = moveJobFromPriorityToActive(KEYS[3], KEYS[2], KEYS[10])
254
247
  if jobId then
255
- return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId,
256
- timestamp, maxJobs, markerKey,
257
- opts)
248
+ return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs, markerKey,
249
+ opts)
258
250
  end
259
251
  end
260
252