bullmq 5.58.9 → 5.60.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.
- package/dist/cjs/classes/child-pool.js +8 -1
- package/dist/cjs/classes/child-pool.js.map +1 -1
- package/dist/cjs/classes/queue.js +9 -0
- package/dist/cjs/classes/queue.js.map +1 -1
- package/dist/cjs/classes/scripts.js +4 -1
- package/dist/cjs/classes/scripts.js.map +1 -1
- package/dist/cjs/classes/worker.js +42 -30
- package/dist/cjs/classes/worker.js.map +1 -1
- package/dist/cjs/commands/changePriority-7.lua +1 -1
- package/dist/cjs/commands/{getRateLimitTtl-1.lua → getRateLimitTtl-2.lua} +6 -0
- package/dist/cjs/commands/includes/deduplicateJob.lua +53 -20
- package/dist/cjs/commands/includes/getTargetQueueList.lua +5 -5
- package/dist/cjs/commands/includes/prepareJobForProcessing.lua +2 -4
- package/dist/cjs/commands/moveJobFromActiveToWait-9.lua +1 -1
- package/dist/cjs/commands/moveStalledJobsToWait-8.lua +0 -1
- package/dist/cjs/commands/moveToActive-11.lua +7 -4
- package/dist/cjs/commands/moveToDelayed-8.lua +2 -1
- package/dist/cjs/commands/moveToFinished-14.lua +10 -7
- package/dist/cjs/scripts/addDelayedJob-6.js +52 -23
- package/dist/cjs/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/cjs/scripts/addJobScheduler-11.js +5 -5
- package/dist/cjs/scripts/addParentJob-5.js +52 -23
- package/dist/cjs/scripts/addParentJob-5.js.map +1 -1
- package/dist/cjs/scripts/addPrioritizedJob-9.js +52 -23
- package/dist/cjs/scripts/addPrioritizedJob-9.js.map +1 -1
- package/dist/cjs/scripts/addRepeatableJob-2.js +5 -5
- package/dist/cjs/scripts/addStandardJob-9.js +52 -23
- package/dist/cjs/scripts/addStandardJob-9.js.map +1 -1
- package/dist/cjs/scripts/changePriority-7.js +5 -5
- package/dist/cjs/scripts/cleanJobsInSet-3.js +5 -5
- package/dist/cjs/scripts/drain-5.js +5 -5
- package/dist/cjs/scripts/{getRateLimitTtl-1.js → getRateLimitTtl-2.js} +7 -2
- package/dist/cjs/scripts/getRateLimitTtl-2.js.map +1 -0
- package/dist/cjs/scripts/index.js +1 -1
- package/dist/cjs/scripts/moveJobFromActiveToWait-9.js +6 -6
- package/dist/cjs/scripts/moveJobsToWait-8.js +5 -5
- package/dist/cjs/scripts/moveStalledJobsToWait-8.js +9 -9
- package/dist/cjs/scripts/moveToActive-11.js +13 -12
- package/dist/cjs/scripts/moveToActive-11.js.map +1 -1
- package/dist/cjs/scripts/moveToDelayed-8.js +1 -1
- package/dist/cjs/scripts/moveToFinished-14.js +16 -15
- package/dist/cjs/scripts/moveToFinished-14.js.map +1 -1
- package/dist/cjs/scripts/obliterate-2.js +5 -5
- package/dist/cjs/scripts/promote-9.js +5 -5
- package/dist/cjs/scripts/removeChildDependency-1.js +5 -5
- package/dist/cjs/scripts/removeJob-2.js +5 -5
- package/dist/cjs/scripts/removeUnprocessedChildren-2.js +5 -5
- package/dist/cjs/scripts/reprocessJob-8.js +5 -5
- package/dist/cjs/scripts/retryJob-11.js +5 -5
- package/dist/cjs/scripts/updateJobScheduler-12.js +5 -5
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/classes/child-pool.js +8 -1
- package/dist/esm/classes/child-pool.js.map +1 -1
- package/dist/esm/classes/queue.d.ts +6 -0
- package/dist/esm/classes/queue.js +9 -0
- package/dist/esm/classes/queue.js.map +1 -1
- package/dist/esm/classes/scripts.js +4 -1
- package/dist/esm/classes/scripts.js.map +1 -1
- package/dist/esm/classes/worker.d.ts +1 -0
- package/dist/esm/classes/worker.js +42 -30
- package/dist/esm/classes/worker.js.map +1 -1
- package/dist/esm/commands/changePriority-7.lua +1 -1
- package/dist/esm/commands/{getRateLimitTtl-1.lua → getRateLimitTtl-2.lua} +6 -0
- package/dist/esm/commands/includes/deduplicateJob.lua +53 -20
- package/dist/esm/commands/includes/getTargetQueueList.lua +5 -5
- package/dist/esm/commands/includes/prepareJobForProcessing.lua +2 -4
- package/dist/esm/commands/moveJobFromActiveToWait-9.lua +1 -1
- package/dist/esm/commands/moveStalledJobsToWait-8.lua +0 -1
- package/dist/esm/commands/moveToActive-11.lua +7 -4
- package/dist/esm/commands/moveToDelayed-8.lua +2 -1
- package/dist/esm/commands/moveToFinished-14.lua +10 -7
- package/dist/esm/interfaces/base-job-options.d.ts +1 -1
- package/dist/esm/interfaces/worker-options.d.ts +8 -0
- package/dist/esm/scripts/addDelayedJob-6.js +52 -23
- package/dist/esm/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/esm/scripts/addJobScheduler-11.js +5 -5
- package/dist/esm/scripts/addParentJob-5.js +52 -23
- package/dist/esm/scripts/addParentJob-5.js.map +1 -1
- package/dist/esm/scripts/addPrioritizedJob-9.js +52 -23
- package/dist/esm/scripts/addPrioritizedJob-9.js.map +1 -1
- package/dist/esm/scripts/addRepeatableJob-2.js +5 -5
- package/dist/esm/scripts/addStandardJob-9.js +52 -23
- package/dist/esm/scripts/addStandardJob-9.js.map +1 -1
- package/dist/esm/scripts/changePriority-7.js +5 -5
- package/dist/esm/scripts/cleanJobsInSet-3.js +5 -5
- package/dist/esm/scripts/drain-5.js +5 -5
- package/dist/esm/scripts/{getRateLimitTtl-1.js → getRateLimitTtl-2.js} +7 -2
- package/dist/esm/scripts/getRateLimitTtl-2.js.map +1 -0
- package/dist/esm/scripts/index.d.ts +1 -1
- package/dist/esm/scripts/index.js +1 -1
- package/dist/esm/scripts/moveJobFromActiveToWait-9.js +6 -6
- package/dist/esm/scripts/moveJobsToWait-8.js +5 -5
- package/dist/esm/scripts/moveStalledJobsToWait-8.js +9 -9
- package/dist/esm/scripts/moveToActive-11.js +13 -12
- package/dist/esm/scripts/moveToActive-11.js.map +1 -1
- package/dist/esm/scripts/moveToDelayed-8.js +1 -1
- package/dist/esm/scripts/moveToFinished-14.js +16 -15
- package/dist/esm/scripts/moveToFinished-14.js.map +1 -1
- package/dist/esm/scripts/obliterate-2.js +5 -5
- package/dist/esm/scripts/promote-9.js +5 -5
- package/dist/esm/scripts/removeChildDependency-1.js +5 -5
- package/dist/esm/scripts/removeJob-2.js +5 -5
- package/dist/esm/scripts/removeUnprocessedChildren-2.js +5 -5
- package/dist/esm/scripts/reprocessJob-8.js +5 -5
- package/dist/esm/scripts/retryJob-11.js +5 -5
- package/dist/esm/scripts/updateJobScheduler-12.js +5 -5
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +1 -1
- package/dist/cjs/scripts/getRateLimitTtl-1.js.map +0 -1
- package/dist/esm/scripts/getRateLimitTtl-1.js.map +0 -1
- /package/dist/esm/scripts/{getRateLimitTtl-1.d.ts → getRateLimitTtl-2.d.ts} +0 -0
|
@@ -3,39 +3,71 @@
|
|
|
3
3
|
]]
|
|
4
4
|
-- Includes
|
|
5
5
|
--- @include "removeJobKeys"
|
|
6
|
+
|
|
7
|
+
local function removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents, currentDeduplicatedJobId,
|
|
8
|
+
jobId, deduplicationId, prefix)
|
|
9
|
+
if rcall("ZREM", delayedKey, currentDeduplicatedJobId) > 0 then
|
|
10
|
+
removeJobKeys(prefix .. currentDeduplicatedJobId)
|
|
11
|
+
rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDeduplicatedJobId,
|
|
12
|
+
"prev", "delayed")
|
|
13
|
+
|
|
14
|
+
-- TODO remove debounced event in next breaking change
|
|
15
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
16
|
+
jobId, "debounceId", deduplicationId)
|
|
17
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
18
|
+
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDeduplicatedJobId)
|
|
19
|
+
|
|
20
|
+
return true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return false
|
|
24
|
+
end
|
|
25
|
+
|
|
6
26
|
local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
7
27
|
prefix)
|
|
8
28
|
local deduplicationId = deduplicationOpts and deduplicationOpts['id']
|
|
9
29
|
if deduplicationId then
|
|
10
30
|
local ttl = deduplicationOpts['ttl']
|
|
11
|
-
if deduplicationOpts['replace']
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
if deduplicationOpts['replace'] then
|
|
32
|
+
if ttl and ttl > 0 then
|
|
33
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
34
|
+
if currentDebounceJobId then
|
|
35
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
36
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
37
|
+
if isRemoved then
|
|
38
|
+
if deduplicationOpts['extend'] then
|
|
39
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
40
|
+
else
|
|
41
|
+
rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
|
|
42
|
+
end
|
|
43
|
+
return
|
|
21
44
|
else
|
|
22
|
-
|
|
45
|
+
return currentDebounceJobId
|
|
23
46
|
end
|
|
24
|
-
|
|
25
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
26
|
-
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDebounceJobId)
|
|
27
|
-
return
|
|
28
47
|
else
|
|
29
|
-
|
|
48
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
49
|
+
return
|
|
30
50
|
end
|
|
31
51
|
else
|
|
32
|
-
rcall('
|
|
33
|
-
|
|
52
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
53
|
+
if currentDebounceJobId then
|
|
54
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
55
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
56
|
+
|
|
57
|
+
if isRemoved then
|
|
58
|
+
rcall('SET', deduplicationKey, jobId)
|
|
59
|
+
return
|
|
60
|
+
else
|
|
61
|
+
return currentDebounceJobId
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
rcall('SET', deduplicationKey, jobId)
|
|
65
|
+
return
|
|
66
|
+
end
|
|
34
67
|
end
|
|
35
68
|
else
|
|
36
|
-
local ttl = deduplicationOpts['ttl']
|
|
37
69
|
local deduplicationKeyExists
|
|
38
|
-
if ttl then
|
|
70
|
+
if ttl and ttl > 0 then
|
|
39
71
|
if deduplicationOpts['extend'] then
|
|
40
72
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
41
73
|
if currentDebounceJobId then
|
|
@@ -58,6 +90,7 @@ local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicatio
|
|
|
58
90
|
|
|
59
91
|
if deduplicationKeyExists then
|
|
60
92
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
93
|
+
-- TODO remove debounced event in next breaking change
|
|
61
94
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
62
95
|
currentDebounceJobId, "debounceId", deduplicationId)
|
|
63
96
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
6
|
local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
|
|
7
|
-
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
|
|
7
|
+
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency", "max", "duration")
|
|
8
8
|
|
|
9
9
|
if queueAttributes[1] then
|
|
10
|
-
return pausedKey, true
|
|
10
|
+
return pausedKey, true, queueAttributes[3], queueAttributes[4]
|
|
11
11
|
else
|
|
12
12
|
if queueAttributes[2] then
|
|
13
13
|
local activeCount = rcall("LLEN", activeKey)
|
|
14
14
|
if activeCount >= tonumber(queueAttributes[2]) then
|
|
15
|
-
return waitKey, true
|
|
15
|
+
return waitKey, true, queueAttributes[3], queueAttributes[4]
|
|
16
16
|
else
|
|
17
|
-
return waitKey, false
|
|
17
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
-
return waitKey, false
|
|
21
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
22
22
|
end
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
--- @include "addBaseMarkerIfNeeded"
|
|
11
11
|
|
|
12
12
|
local function prepareJobForProcessing(keyPrefix, rateLimiterKey, eventStreamKey,
|
|
13
|
-
jobId, processedOn, maxJobs, markerKey, opts)
|
|
13
|
+
jobId, processedOn, maxJobs, limiterDuration, markerKey, opts)
|
|
14
14
|
local jobKey = keyPrefix .. jobId
|
|
15
15
|
|
|
16
16
|
-- Check if we need to perform rate limiting.
|
|
@@ -18,16 +18,14 @@ local function prepareJobForProcessing(keyPrefix, rateLimiterKey, eventStreamKey
|
|
|
18
18
|
local jobCounter = tonumber(rcall("INCR", rateLimiterKey))
|
|
19
19
|
|
|
20
20
|
if jobCounter == 1 then
|
|
21
|
-
local limiterDuration = opts['limiter'] and opts['limiter']['duration']
|
|
22
21
|
local integerDuration = math.floor(math.abs(limiterDuration))
|
|
23
22
|
rcall("PEXPIRE", rateLimiterKey, integerDuration)
|
|
24
23
|
end
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
local lockKey = jobKey .. ':lock'
|
|
28
|
-
|
|
29
26
|
-- get a lock
|
|
30
27
|
if opts['token'] ~= "0" then
|
|
28
|
+
local lockKey = jobKey .. ':lock'
|
|
31
29
|
rcall("SET", lockKey, opts['token'], "PX", opts['lockDuration'])
|
|
32
30
|
end
|
|
33
31
|
|
|
@@ -51,14 +51,15 @@ local opts = cmsgpack.unpack(ARGV[3])
|
|
|
51
51
|
--- @include "includes/prepareJobForProcessing"
|
|
52
52
|
--- @include "includes/promoteDelayedJobs"
|
|
53
53
|
|
|
54
|
-
local target, isPausedOrMaxed = getTargetQueueList(KEYS[9],
|
|
54
|
+
local target, isPausedOrMaxed, rateLimitMax, rateLimitDuration = getTargetQueueList(KEYS[9],
|
|
55
|
+
activeKey, waitKey, KEYS[8])
|
|
55
56
|
|
|
56
57
|
-- Check if there are delayed jobs that we can move to wait.
|
|
57
58
|
local markerKey = KEYS[11]
|
|
58
59
|
promoteDelayedJobs(delayedKey, markerKey, target, KEYS[3], eventStreamKey, ARGV[1],
|
|
59
60
|
ARGV[2], KEYS[10], isPausedOrMaxed)
|
|
60
61
|
|
|
61
|
-
local maxJobs = tonumber(opts['limiter'] and opts['limiter']['max'])
|
|
62
|
+
local maxJobs = tonumber(rateLimitMax or (opts['limiter'] and opts['limiter']['max']))
|
|
62
63
|
local expireTime = getRateLimitTTL(maxJobs, rateLimiterKey)
|
|
63
64
|
|
|
64
65
|
-- Check if we are rate limited first.
|
|
@@ -67,6 +68,8 @@ if expireTime > 0 then return {0, 0, expireTime, 0} end
|
|
|
67
68
|
-- paused or maxed queue
|
|
68
69
|
if isPausedOrMaxed then return {0, 0, 0, 0} end
|
|
69
70
|
|
|
71
|
+
local limiterDuration = (opts['limiter'] and opts['limiter']['duration']) or rateLimitDuration
|
|
72
|
+
|
|
70
73
|
-- no job ID, try non-blocking move from wait to active
|
|
71
74
|
local jobId = rcall("RPOPLPUSH", waitKey, activeKey)
|
|
72
75
|
|
|
@@ -78,12 +81,12 @@ end
|
|
|
78
81
|
|
|
79
82
|
if jobId then
|
|
80
83
|
return prepareJobForProcessing(ARGV[1], rateLimiterKey, eventStreamKey, jobId, ARGV[2],
|
|
81
|
-
maxJobs, markerKey, opts)
|
|
84
|
+
maxJobs, limiterDuration, markerKey, opts)
|
|
82
85
|
else
|
|
83
86
|
jobId = moveJobFromPrioritizedToActive(KEYS[3], activeKey, KEYS[10])
|
|
84
87
|
if jobId then
|
|
85
88
|
return prepareJobForProcessing(ARGV[1], rateLimiterKey, eventStreamKey, jobId, ARGV[2],
|
|
86
|
-
maxJobs, markerKey, opts)
|
|
89
|
+
maxJobs, limiterDuration, markerKey, opts)
|
|
87
90
|
end
|
|
88
91
|
end
|
|
89
92
|
|
|
@@ -50,11 +50,12 @@ if rcall("EXISTS", jobKey) == 1 then
|
|
|
50
50
|
local delayedKey = KEYS[4]
|
|
51
51
|
local jobId = ARGV[3]
|
|
52
52
|
local delay = tonumber(ARGV[5])
|
|
53
|
-
local score, delayedTimestamp = getDelayedScore(delayedKey, ARGV[2], delay)
|
|
54
53
|
|
|
55
54
|
local numRemovedElements = rcall("LREM", KEYS[2], -1, jobId)
|
|
56
55
|
if numRemovedElements < 1 then return -3 end
|
|
57
56
|
|
|
57
|
+
local score, delayedTimestamp = getDelayedScore(delayedKey, ARGV[2], delay)
|
|
58
|
+
|
|
58
59
|
if ARGV[6] == "0" then
|
|
59
60
|
rcall("HINCRBY", jobKey, "atm", 1)
|
|
60
61
|
end
|
|
@@ -209,14 +209,15 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
|
209
209
|
-- and not rate limited.
|
|
210
210
|
if (ARGV[6] == "1") then
|
|
211
211
|
|
|
212
|
-
local target, isPausedOrMaxed = getTargetQueueList(metaKey, KEYS[2],
|
|
212
|
+
local target, isPausedOrMaxed, rateLimitMax, rateLimitDuration = getTargetQueueList(metaKey, KEYS[2],
|
|
213
|
+
KEYS[1], KEYS[8])
|
|
213
214
|
|
|
214
215
|
local markerKey = KEYS[14]
|
|
215
216
|
-- Check if there are delayed jobs that can be promoted
|
|
216
217
|
promoteDelayedJobs(KEYS[7], markerKey, target, KEYS[3], eventStreamKey, prefix, timestamp, KEYS[10],
|
|
217
218
|
isPausedOrMaxed)
|
|
218
219
|
|
|
219
|
-
local maxJobs = tonumber(opts['limiter'] and opts['limiter']['max'])
|
|
220
|
+
local maxJobs = tonumber(rateLimitMax or (opts['limiter'] and opts['limiter']['max']))
|
|
220
221
|
-- Check if we are rate limited first.
|
|
221
222
|
local expireTime = getRateLimitTTL(maxJobs, KEYS[6])
|
|
222
223
|
|
|
@@ -229,6 +230,8 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
|
229
230
|
return {0, 0, 0, 0}
|
|
230
231
|
end
|
|
231
232
|
|
|
233
|
+
local limiterDuration = (opts['limiter'] and opts['limiter']['duration']) or rateLimitDuration
|
|
234
|
+
|
|
232
235
|
jobId = rcall("RPOPLPUSH", KEYS[1], KEYS[2])
|
|
233
236
|
|
|
234
237
|
if jobId then
|
|
@@ -241,17 +244,17 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
|
241
244
|
if jobId == "0:0" then
|
|
242
245
|
jobId = moveJobFromPrioritizedToActive(KEYS[3], KEYS[2], KEYS[10])
|
|
243
246
|
return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
|
|
244
|
-
markerKey, opts)
|
|
247
|
+
limiterDuration, markerKey, opts)
|
|
245
248
|
end
|
|
246
249
|
else
|
|
247
|
-
return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
|
|
248
|
-
opts)
|
|
250
|
+
return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
|
|
251
|
+
limiterDuration, markerKey, opts)
|
|
249
252
|
end
|
|
250
253
|
else
|
|
251
254
|
jobId = moveJobFromPrioritizedToActive(KEYS[3], KEYS[2], KEYS[10])
|
|
252
255
|
if jobId then
|
|
253
|
-
return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
|
|
254
|
-
opts)
|
|
256
|
+
return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
|
|
257
|
+
limiterDuration, markerKey, opts)
|
|
255
258
|
end
|
|
256
259
|
end
|
|
257
260
|
|
|
@@ -36,6 +36,14 @@ export interface WorkerOptions extends QueueBaseOptions, SandboxedOptions {
|
|
|
36
36
|
* @see {@link https://docs.bullmq.io/guide/metrics}
|
|
37
37
|
*/
|
|
38
38
|
metrics?: MetricsOptions;
|
|
39
|
+
/**
|
|
40
|
+
* Defines the maximum number of times a job is allowed to start processing,
|
|
41
|
+
* regardless of whether it completes or fails. Each time a worker picks up the job
|
|
42
|
+
* and begins processing it, the attemptsStarted counter is incremented.
|
|
43
|
+
* If this counter reaches maxStartedAttempts, the job will be moved to the failed state with an UnrecoverableError.
|
|
44
|
+
* @defaultValue undefined
|
|
45
|
+
*/
|
|
46
|
+
maxStartedAttempts?: number;
|
|
39
47
|
/**
|
|
40
48
|
* Amount of times a job can be recovered from a stalled state
|
|
41
49
|
* to the `wait` state. If this is exceeded, the job is moved
|
|
@@ -120,37 +120,65 @@ local function removeJobKeys(jobKey)
|
|
|
120
120
|
return rcall("DEL", jobKey, jobKey .. ':logs', jobKey .. ':dependencies',
|
|
121
121
|
jobKey .. ':processed', jobKey .. ':failed', jobKey .. ':unsuccessful')
|
|
122
122
|
end
|
|
123
|
+
local function removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents, currentDeduplicatedJobId,
|
|
124
|
+
jobId, deduplicationId, prefix)
|
|
125
|
+
if rcall("ZREM", delayedKey, currentDeduplicatedJobId) > 0 then
|
|
126
|
+
removeJobKeys(prefix .. currentDeduplicatedJobId)
|
|
127
|
+
rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDeduplicatedJobId,
|
|
128
|
+
"prev", "delayed")
|
|
129
|
+
-- TODO remove debounced event in next breaking change
|
|
130
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
131
|
+
jobId, "debounceId", deduplicationId)
|
|
132
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
133
|
+
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDeduplicatedJobId)
|
|
134
|
+
return true
|
|
135
|
+
end
|
|
136
|
+
return false
|
|
137
|
+
end
|
|
123
138
|
local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
124
139
|
prefix)
|
|
125
140
|
local deduplicationId = deduplicationOpts and deduplicationOpts['id']
|
|
126
141
|
if deduplicationId then
|
|
127
142
|
local ttl = deduplicationOpts['ttl']
|
|
128
|
-
if deduplicationOpts['replace']
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
if deduplicationOpts['replace'] then
|
|
144
|
+
if ttl and ttl > 0 then
|
|
145
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
146
|
+
if currentDebounceJobId then
|
|
147
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
148
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
149
|
+
if isRemoved then
|
|
150
|
+
if deduplicationOpts['extend'] then
|
|
151
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
152
|
+
else
|
|
153
|
+
rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
|
|
154
|
+
end
|
|
155
|
+
return
|
|
137
156
|
else
|
|
138
|
-
|
|
157
|
+
return currentDebounceJobId
|
|
139
158
|
end
|
|
140
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
141
|
-
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDebounceJobId)
|
|
142
|
-
return
|
|
143
159
|
else
|
|
144
|
-
|
|
160
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
161
|
+
return
|
|
145
162
|
end
|
|
146
163
|
else
|
|
147
|
-
rcall('
|
|
148
|
-
|
|
164
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
165
|
+
if currentDebounceJobId then
|
|
166
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
167
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
168
|
+
if isRemoved then
|
|
169
|
+
rcall('SET', deduplicationKey, jobId)
|
|
170
|
+
return
|
|
171
|
+
else
|
|
172
|
+
return currentDebounceJobId
|
|
173
|
+
end
|
|
174
|
+
else
|
|
175
|
+
rcall('SET', deduplicationKey, jobId)
|
|
176
|
+
return
|
|
177
|
+
end
|
|
149
178
|
end
|
|
150
179
|
else
|
|
151
|
-
local ttl = deduplicationOpts['ttl']
|
|
152
180
|
local deduplicationKeyExists
|
|
153
|
-
if ttl then
|
|
181
|
+
if ttl and ttl > 0 then
|
|
154
182
|
if deduplicationOpts['extend'] then
|
|
155
183
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
156
184
|
if currentDebounceJobId then
|
|
@@ -172,6 +200,7 @@ local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicatio
|
|
|
172
200
|
end
|
|
173
201
|
if deduplicationKeyExists then
|
|
174
202
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
203
|
+
-- TODO remove debounced event in next breaking change
|
|
175
204
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
176
205
|
currentDebounceJobId, "debounceId", deduplicationId)
|
|
177
206
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
@@ -274,20 +303,20 @@ end
|
|
|
274
303
|
(since an empty list and !EXISTS are not really the same).
|
|
275
304
|
]]
|
|
276
305
|
local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
|
|
277
|
-
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
|
|
306
|
+
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency", "max", "duration")
|
|
278
307
|
if queueAttributes[1] then
|
|
279
|
-
return pausedKey, true
|
|
308
|
+
return pausedKey, true, queueAttributes[3], queueAttributes[4]
|
|
280
309
|
else
|
|
281
310
|
if queueAttributes[2] then
|
|
282
311
|
local activeCount = rcall("LLEN", activeKey)
|
|
283
312
|
if activeCount >= tonumber(queueAttributes[2]) then
|
|
284
|
-
return waitKey, true
|
|
313
|
+
return waitKey, true, queueAttributes[3], queueAttributes[4]
|
|
285
314
|
else
|
|
286
|
-
return waitKey, false
|
|
315
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
287
316
|
end
|
|
288
317
|
end
|
|
289
318
|
end
|
|
290
|
-
return waitKey, false
|
|
319
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
291
320
|
end
|
|
292
321
|
local function moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
|
293
322
|
local parentWaitKey = parentQueueKey .. ":wait"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addDelayedJob-6.js","sourceRoot":"","sources":["../../../src/scripts/addDelayedJob-6.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG
|
|
1
|
+
{"version":3,"file":"addDelayedJob-6.js","sourceRoot":"","sources":["../../../src/scripts/addDelayedJob-6.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAudf,CAAC;AACF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|
|
@@ -179,20 +179,20 @@ end
|
|
|
179
179
|
(since an empty list and !EXISTS are not really the same).
|
|
180
180
|
]]
|
|
181
181
|
local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
|
|
182
|
-
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
|
|
182
|
+
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency", "max", "duration")
|
|
183
183
|
if queueAttributes[1] then
|
|
184
|
-
return pausedKey, true
|
|
184
|
+
return pausedKey, true, queueAttributes[3], queueAttributes[4]
|
|
185
185
|
else
|
|
186
186
|
if queueAttributes[2] then
|
|
187
187
|
local activeCount = rcall("LLEN", activeKey)
|
|
188
188
|
if activeCount >= tonumber(queueAttributes[2]) then
|
|
189
|
-
return waitKey, true
|
|
189
|
+
return waitKey, true, queueAttributes[3], queueAttributes[4]
|
|
190
190
|
else
|
|
191
|
-
return waitKey, false
|
|
191
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
192
192
|
end
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
|
-
return waitKey, false
|
|
195
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
196
196
|
end
|
|
197
197
|
--[[
|
|
198
198
|
Function to add job in target list and add marker if needed.
|
|
@@ -53,37 +53,65 @@ local function removeJobKeys(jobKey)
|
|
|
53
53
|
return rcall("DEL", jobKey, jobKey .. ':logs', jobKey .. ':dependencies',
|
|
54
54
|
jobKey .. ':processed', jobKey .. ':failed', jobKey .. ':unsuccessful')
|
|
55
55
|
end
|
|
56
|
+
local function removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents, currentDeduplicatedJobId,
|
|
57
|
+
jobId, deduplicationId, prefix)
|
|
58
|
+
if rcall("ZREM", delayedKey, currentDeduplicatedJobId) > 0 then
|
|
59
|
+
removeJobKeys(prefix .. currentDeduplicatedJobId)
|
|
60
|
+
rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDeduplicatedJobId,
|
|
61
|
+
"prev", "delayed")
|
|
62
|
+
-- TODO remove debounced event in next breaking change
|
|
63
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
64
|
+
jobId, "debounceId", deduplicationId)
|
|
65
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
66
|
+
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDeduplicatedJobId)
|
|
67
|
+
return true
|
|
68
|
+
end
|
|
69
|
+
return false
|
|
70
|
+
end
|
|
56
71
|
local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
57
72
|
prefix)
|
|
58
73
|
local deduplicationId = deduplicationOpts and deduplicationOpts['id']
|
|
59
74
|
if deduplicationId then
|
|
60
75
|
local ttl = deduplicationOpts['ttl']
|
|
61
|
-
if deduplicationOpts['replace']
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
if deduplicationOpts['replace'] then
|
|
77
|
+
if ttl and ttl > 0 then
|
|
78
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
79
|
+
if currentDebounceJobId then
|
|
80
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
81
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
82
|
+
if isRemoved then
|
|
83
|
+
if deduplicationOpts['extend'] then
|
|
84
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
85
|
+
else
|
|
86
|
+
rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
|
|
87
|
+
end
|
|
88
|
+
return
|
|
70
89
|
else
|
|
71
|
-
|
|
90
|
+
return currentDebounceJobId
|
|
72
91
|
end
|
|
73
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
74
|
-
jobId, "deduplicationId", deduplicationId, "deduplicatedJobId", currentDebounceJobId)
|
|
75
|
-
return
|
|
76
92
|
else
|
|
77
|
-
|
|
93
|
+
rcall('SET', deduplicationKey, jobId, 'PX', ttl)
|
|
94
|
+
return
|
|
78
95
|
end
|
|
79
96
|
else
|
|
80
|
-
rcall('
|
|
81
|
-
|
|
97
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
98
|
+
if currentDebounceJobId then
|
|
99
|
+
local isRemoved = removeDelayedJob(delayedKey, deduplicationKey, eventsKey, maxEvents,
|
|
100
|
+
currentDebounceJobId, jobId, deduplicationId, prefix)
|
|
101
|
+
if isRemoved then
|
|
102
|
+
rcall('SET', deduplicationKey, jobId)
|
|
103
|
+
return
|
|
104
|
+
else
|
|
105
|
+
return currentDebounceJobId
|
|
106
|
+
end
|
|
107
|
+
else
|
|
108
|
+
rcall('SET', deduplicationKey, jobId)
|
|
109
|
+
return
|
|
110
|
+
end
|
|
82
111
|
end
|
|
83
112
|
else
|
|
84
|
-
local ttl = deduplicationOpts['ttl']
|
|
85
113
|
local deduplicationKeyExists
|
|
86
|
-
if ttl then
|
|
114
|
+
if ttl and ttl > 0 then
|
|
87
115
|
if deduplicationOpts['extend'] then
|
|
88
116
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
89
117
|
if currentDebounceJobId then
|
|
@@ -105,6 +133,7 @@ local function deduplicateJob(deduplicationOpts, jobId, delayedKey, deduplicatio
|
|
|
105
133
|
end
|
|
106
134
|
if deduplicationKeyExists then
|
|
107
135
|
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
|
136
|
+
-- TODO remove debounced event in next breaking change
|
|
108
137
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "debounced", "jobId",
|
|
109
138
|
currentDebounceJobId, "debounceId", deduplicationId)
|
|
110
139
|
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "deduplicated", "jobId",
|
|
@@ -231,20 +260,20 @@ end
|
|
|
231
260
|
(since an empty list and !EXISTS are not really the same).
|
|
232
261
|
]]
|
|
233
262
|
local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
|
|
234
|
-
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
|
|
263
|
+
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency", "max", "duration")
|
|
235
264
|
if queueAttributes[1] then
|
|
236
|
-
return pausedKey, true
|
|
265
|
+
return pausedKey, true, queueAttributes[3], queueAttributes[4]
|
|
237
266
|
else
|
|
238
267
|
if queueAttributes[2] then
|
|
239
268
|
local activeCount = rcall("LLEN", activeKey)
|
|
240
269
|
if activeCount >= tonumber(queueAttributes[2]) then
|
|
241
|
-
return waitKey, true
|
|
270
|
+
return waitKey, true, queueAttributes[3], queueAttributes[4]
|
|
242
271
|
else
|
|
243
|
-
return waitKey, false
|
|
272
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
244
273
|
end
|
|
245
274
|
end
|
|
246
275
|
end
|
|
247
|
-
return waitKey, false
|
|
276
|
+
return waitKey, false, queueAttributes[3], queueAttributes[4]
|
|
248
277
|
end
|
|
249
278
|
local function moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
|
250
279
|
local parentWaitKey = parentQueueKey .. ":wait"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addParentJob-5.js","sourceRoot":"","sources":["../../../src/scripts/addParentJob-5.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG
|
|
1
|
+
{"version":3,"file":"addParentJob-5.js","sourceRoot":"","sources":["../../../src/scripts/addParentJob-5.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+af,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,cAAc;IACpB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|