bullmq 5.47.2 → 5.48.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 (58) hide show
  1. package/dist/cjs/classes/async-fifo-queue.js.map +1 -1
  2. package/dist/cjs/classes/child.js.map +1 -1
  3. package/dist/cjs/classes/job-scheduler.js +1 -1
  4. package/dist/cjs/classes/job-scheduler.js.map +1 -1
  5. package/dist/cjs/classes/job.js +11 -0
  6. package/dist/cjs/classes/job.js.map +1 -1
  7. package/dist/cjs/classes/queue-base.js.map +1 -1
  8. package/dist/cjs/classes/queue-keys.js.map +1 -1
  9. package/dist/cjs/classes/repeat.js +1 -1
  10. package/dist/cjs/classes/repeat.js.map +1 -1
  11. package/dist/cjs/classes/scripts.js +12 -2
  12. package/dist/cjs/classes/scripts.js.map +1 -1
  13. package/dist/cjs/classes/worker.js.map +1 -1
  14. package/dist/cjs/commands/includes/isLocked.lua +1 -0
  15. package/dist/cjs/commands/includes/removeJobWithChildren.lua +93 -0
  16. package/dist/cjs/commands/removeJob-3.lua +15 -72
  17. package/dist/cjs/commands/removeUnprocessedChildren-2.lua +31 -0
  18. package/dist/cjs/scripts/index.js +1 -0
  19. package/dist/cjs/scripts/index.js.map +1 -1
  20. package/dist/cjs/scripts/removeJob-3.js +83 -55
  21. package/dist/cjs/scripts/removeJob-3.js.map +1 -1
  22. package/dist/cjs/scripts/removeUnprocessedChildren-2.js +332 -0
  23. package/dist/cjs/scripts/removeUnprocessedChildren-2.js.map +1 -0
  24. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  25. package/dist/cjs/version.js +1 -1
  26. package/dist/esm/classes/async-fifo-queue.js.map +1 -1
  27. package/dist/esm/classes/child.js.map +1 -1
  28. package/dist/esm/classes/job-scheduler.js +1 -1
  29. package/dist/esm/classes/job-scheduler.js.map +1 -1
  30. package/dist/esm/classes/job.d.ts +9 -1
  31. package/dist/esm/classes/job.js +11 -0
  32. package/dist/esm/classes/job.js.map +1 -1
  33. package/dist/esm/classes/queue-base.js.map +1 -1
  34. package/dist/esm/classes/queue-keys.js.map +1 -1
  35. package/dist/esm/classes/repeat.js +1 -1
  36. package/dist/esm/classes/repeat.js.map +1 -1
  37. package/dist/esm/classes/scripts.d.ts +1 -0
  38. package/dist/esm/classes/scripts.js +12 -2
  39. package/dist/esm/classes/scripts.js.map +1 -1
  40. package/dist/esm/classes/worker.js.map +1 -1
  41. package/dist/esm/commands/includes/isLocked.lua +1 -0
  42. package/dist/esm/commands/includes/removeJobWithChildren.lua +93 -0
  43. package/dist/esm/commands/removeJob-3.lua +15 -72
  44. package/dist/esm/commands/removeUnprocessedChildren-2.lua +31 -0
  45. package/dist/esm/interfaces/queue-options.d.ts +1 -1
  46. package/dist/esm/interfaces/repeat-options.d.ts +1 -1
  47. package/dist/esm/scripts/index.d.ts +1 -0
  48. package/dist/esm/scripts/index.js +1 -0
  49. package/dist/esm/scripts/index.js.map +1 -1
  50. package/dist/esm/scripts/removeJob-3.js +83 -55
  51. package/dist/esm/scripts/removeJob-3.js.map +1 -1
  52. package/dist/esm/scripts/removeUnprocessedChildren-2.d.ts +5 -0
  53. package/dist/esm/scripts/removeUnprocessedChildren-2.js +329 -0
  54. package/dist/esm/scripts/removeUnprocessedChildren-2.js.map +1 -0
  55. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  56. package/dist/esm/version.d.ts +1 -1
  57. package/dist/esm/version.js +1 -1
  58. package/package.json +1 -1
@@ -0,0 +1,329 @@
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.
59
+ ]]
60
+ local function removeDeduplicationKey(prefixKey, jobKey)
61
+ local deduplicationId = rcall("HGET", jobKey, "deid")
62
+ if deduplicationId then
63
+ local deduplicationKey = prefixKey .. "de:" .. deduplicationId
64
+ rcall("DEL", deduplicationKey)
65
+ end
66
+ end
67
+ --[[
68
+ Function to remove from any state.
69
+ returns:
70
+ prev state
71
+ ]]
72
+ local function removeJobFromAnyState( prefix, jobId)
73
+ -- We start with the ZSCORE checks, since they have O(1) complexity
74
+ if rcall("ZSCORE", prefix .. "completed", jobId) then
75
+ rcall("ZREM", prefix .. "completed", jobId)
76
+ return "completed"
77
+ elseif rcall("ZSCORE", prefix .. "waiting-children", jobId) then
78
+ rcall("ZREM", prefix .. "waiting-children", jobId)
79
+ return "waiting-children"
80
+ elseif rcall("ZSCORE", prefix .. "delayed", jobId) then
81
+ rcall("ZREM", prefix .. "delayed", jobId)
82
+ return "delayed"
83
+ elseif rcall("ZSCORE", prefix .. "failed", jobId) then
84
+ rcall("ZREM", prefix .. "failed", jobId)
85
+ return "failed"
86
+ elseif rcall("ZSCORE", prefix .. "prioritized", jobId) then
87
+ rcall("ZREM", prefix .. "prioritized", jobId)
88
+ return "prioritized"
89
+ -- We remove only 1 element from the list, since we assume they are not added multiple times
90
+ elseif rcall("LREM", prefix .. "wait", 1, jobId) == 1 then
91
+ return "wait"
92
+ elseif rcall("LREM", prefix .. "paused", 1, jobId) == 1 then
93
+ return "paused"
94
+ elseif rcall("LREM", prefix .. "active", 1, jobId) == 1 then
95
+ return "active"
96
+ end
97
+ return "unknown"
98
+ end
99
+ --[[
100
+ Function to remove job keys.
101
+ ]]
102
+ local function removeJobKeys(jobKey)
103
+ return rcall("DEL", jobKey, jobKey .. ':logs', jobKey .. ':dependencies',
104
+ jobKey .. ':processed', jobKey .. ':failed', jobKey .. ':unsuccessful')
105
+ end
106
+ --[[
107
+ Check if this job has a parent. If so we will just remove it from
108
+ the parent child list, but if it is the last child we should move the parent to "wait/paused"
109
+ which requires code from "moveToFinished"
110
+ ]]
111
+ -- Includes
112
+ --[[
113
+ Function to add job in target list and add marker if needed.
114
+ ]]
115
+ -- Includes
116
+ --[[
117
+ Add marker if needed when a job is available.
118
+ ]]
119
+ local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
120
+ if not isPausedOrMaxed then
121
+ rcall("ZADD", markerKey, 0, "0")
122
+ end
123
+ end
124
+ local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
125
+ rcall(pushCmd, targetKey, jobId)
126
+ addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
127
+ end
128
+ --[[
129
+ Function to check for the meta.paused key to decide if we are paused or not
130
+ (since an empty list and !EXISTS are not really the same).
131
+ ]]
132
+ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
133
+ local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
134
+ if queueAttributes[1] then
135
+ return pausedKey, true
136
+ else
137
+ if queueAttributes[2] then
138
+ local activeCount = rcall("LLEN", activeKey)
139
+ if activeCount >= tonumber(queueAttributes[2]) then
140
+ return waitKey, true
141
+ else
142
+ return waitKey, false
143
+ end
144
+ end
145
+ end
146
+ return waitKey, false
147
+ end
148
+ local function _moveParentToWait(parentPrefix, parentId, emitEvent)
149
+ local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
150
+ parentPrefix .. "wait", parentPrefix .. "paused")
151
+ addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
152
+ if emitEvent then
153
+ local parentEventStream = parentPrefix .. "events"
154
+ rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
155
+ end
156
+ end
157
+ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
158
+ if parentKey then
159
+ local parentDependenciesKey = parentKey .. ":dependencies"
160
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
161
+ if result > 0 then
162
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
163
+ if pendingDependencies == 0 then
164
+ local parentId = getJobIdFromKey(parentKey)
165
+ local parentPrefix = getJobKeyPrefix(parentKey, parentId)
166
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
167
+ if numRemovedElements == 1 then
168
+ if hard then -- remove parent in same queue
169
+ if parentPrefix == baseKey then
170
+ removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
171
+ removeJobKeys(parentKey)
172
+ if debounceId then
173
+ rcall("DEL", parentPrefix .. "de:" .. debounceId)
174
+ end
175
+ else
176
+ _moveParentToWait(parentPrefix, parentId)
177
+ end
178
+ else
179
+ _moveParentToWait(parentPrefix, parentId, true)
180
+ end
181
+ end
182
+ end
183
+ return true
184
+ end
185
+ else
186
+ local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
187
+ local missedParentKey = parentAttributes[1]
188
+ if( (type(missedParentKey) == "string") and missedParentKey ~= ""
189
+ and (rcall("EXISTS", missedParentKey) == 1)) then
190
+ local parentDependenciesKey = missedParentKey .. ":dependencies"
191
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
192
+ if result > 0 then
193
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
194
+ if pendingDependencies == 0 then
195
+ local parentId = getJobIdFromKey(missedParentKey)
196
+ local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
197
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
198
+ if numRemovedElements == 1 then
199
+ if hard then
200
+ if parentPrefix == baseKey then
201
+ removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
202
+ removeJobKeys(missedParentKey)
203
+ if parentAttributes[2] then
204
+ rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
205
+ end
206
+ else
207
+ _moveParentToWait(parentPrefix, parentId)
208
+ end
209
+ else
210
+ _moveParentToWait(parentPrefix, parentId, true)
211
+ end
212
+ end
213
+ end
214
+ return true
215
+ end
216
+ end
217
+ end
218
+ return false
219
+ end
220
+ --[[
221
+ Function to recursively check if there are no locks
222
+ on the jobs to be removed.
223
+ returns:
224
+ boolean
225
+ ]]
226
+ local function isLocked( prefix, jobId, removeChildren)
227
+ local jobKey = prefix .. jobId;
228
+ -- Check if this job is locked
229
+ local lockKey = jobKey .. ':lock'
230
+ local lock = rcall("GET", lockKey)
231
+ if not lock then
232
+ if removeChildren == "1" then
233
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
234
+ if (#dependencies > 0) then
235
+ for i, childJobKey in ipairs(dependencies) do
236
+ -- We need to get the jobId for this job.
237
+ local childJobId = getJobIdFromKey(childJobKey)
238
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
239
+ local result = isLocked( childJobPrefix, childJobId, removeChildren )
240
+ if result then
241
+ return true
242
+ end
243
+ end
244
+ end
245
+ end
246
+ return false
247
+ end
248
+ return true
249
+ end
250
+ local removeJobChildren
251
+ local removeJobWithChildren
252
+ removeJobChildren = function(prefix, meta, jobKey, options)
253
+ -- Check if this job has children
254
+ -- If so, we are going to try to remove the children recursively in a depth-first way
255
+ -- because if some job is locked, we must exit with an error.
256
+ if not options.ignoreProcessed then
257
+ local processed = rcall("HGETALL", jobKey .. ":processed")
258
+ if #processed > 0 then
259
+ for i = 1, #processed, 2 do
260
+ local childJobId = getJobIdFromKey(processed[i])
261
+ local childJobPrefix = getJobKeyPrefix(processed[i], childJobId)
262
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
263
+ end
264
+ end
265
+ local failed = rcall("HGETALL", jobKey .. ":failed")
266
+ if #failed > 0 then
267
+ for i = 1, #failed, 2 do
268
+ local childJobId = getJobIdFromKey(failed[i])
269
+ local childJobPrefix = getJobKeyPrefix(failed[i], childJobId)
270
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
271
+ end
272
+ end
273
+ local unsuccessful = rcall("ZRANGE", jobKey .. ":unsuccessful", 0, -1)
274
+ if #unsuccessful > 0 then
275
+ for i = 1, #unsuccessful, 1 do
276
+ local childJobId = getJobIdFromKey(unsuccessful[i])
277
+ local childJobPrefix = getJobKeyPrefix(unsuccessful[i], childJobId)
278
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
279
+ end
280
+ end
281
+ end
282
+ local dependencies = rcall("SMEMBERS", jobKey .. ":dependencies")
283
+ if #dependencies > 0 then
284
+ for i, childJobKey in ipairs(dependencies) do
285
+ local childJobId = getJobIdFromKey(childJobKey)
286
+ local childJobPrefix = getJobKeyPrefix(childJobKey, childJobId)
287
+ removeJobWithChildren(childJobPrefix, meta, childJobId, jobKey, options)
288
+ end
289
+ end
290
+ end
291
+ removeJobWithChildren = function(prefix, meta, jobId, parentKey, options)
292
+ local jobKey = prefix .. jobId
293
+ if options.ignoreLocked then
294
+ if isLocked(prefix, jobId) then
295
+ return
296
+ end
297
+ end
298
+ -- Check if job is in the failed zset
299
+ local failedSet = prefix .. "failed"
300
+ if not (options.ignoreProcessed and rcall("ZSCORE", failedSet, jobId)) then
301
+ removeParentDependencyKey(jobKey, false, parentKey, nil)
302
+ if options.removeChildren then
303
+ removeJobChildren(prefix, meta, jobKey, options)
304
+ end
305
+ local prev = removeJobFromAnyState(prefix, jobId)
306
+ removeDeduplicationKey(prefix, jobKey)
307
+ if removeJobKeys(jobKey) > 0 then
308
+ local maxEvents = getOrSetMaxEvents(meta)
309
+ rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed", "jobId", jobId, "prev", prev)
310
+ end
311
+ end
312
+ end
313
+ local prefix = ARGV[1]
314
+ local jobId = ARGV[2]
315
+ local jobKey = KEYS[1]
316
+ local metaKey = KEYS[2]
317
+ local options = {
318
+ removeChildren = "1",
319
+ ignoreProcessed = true,
320
+ ignoreLocked = true
321
+ }
322
+ removeJobChildren(prefix, metaKey, jobKey, options)
323
+ `;
324
+ export const removeUnprocessedChildren = {
325
+ name: 'removeUnprocessedChildren',
326
+ content,
327
+ keys: 2,
328
+ };
329
+ //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkUf,CAAC;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,2BAA2B;IACjC,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}