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.
Files changed (114) hide show
  1. package/dist/cjs/classes/child-pool.js +8 -1
  2. package/dist/cjs/classes/child-pool.js.map +1 -1
  3. package/dist/cjs/classes/queue.js +9 -0
  4. package/dist/cjs/classes/queue.js.map +1 -1
  5. package/dist/cjs/classes/scripts.js +4 -1
  6. package/dist/cjs/classes/scripts.js.map +1 -1
  7. package/dist/cjs/classes/worker.js +42 -30
  8. package/dist/cjs/classes/worker.js.map +1 -1
  9. package/dist/cjs/commands/changePriority-7.lua +1 -1
  10. package/dist/cjs/commands/{getRateLimitTtl-1.lua → getRateLimitTtl-2.lua} +6 -0
  11. package/dist/cjs/commands/includes/deduplicateJob.lua +53 -20
  12. package/dist/cjs/commands/includes/getTargetQueueList.lua +5 -5
  13. package/dist/cjs/commands/includes/prepareJobForProcessing.lua +2 -4
  14. package/dist/cjs/commands/moveJobFromActiveToWait-9.lua +1 -1
  15. package/dist/cjs/commands/moveStalledJobsToWait-8.lua +0 -1
  16. package/dist/cjs/commands/moveToActive-11.lua +7 -4
  17. package/dist/cjs/commands/moveToDelayed-8.lua +2 -1
  18. package/dist/cjs/commands/moveToFinished-14.lua +10 -7
  19. package/dist/cjs/scripts/addDelayedJob-6.js +52 -23
  20. package/dist/cjs/scripts/addDelayedJob-6.js.map +1 -1
  21. package/dist/cjs/scripts/addJobScheduler-11.js +5 -5
  22. package/dist/cjs/scripts/addParentJob-5.js +52 -23
  23. package/dist/cjs/scripts/addParentJob-5.js.map +1 -1
  24. package/dist/cjs/scripts/addPrioritizedJob-9.js +52 -23
  25. package/dist/cjs/scripts/addPrioritizedJob-9.js.map +1 -1
  26. package/dist/cjs/scripts/addRepeatableJob-2.js +5 -5
  27. package/dist/cjs/scripts/addStandardJob-9.js +52 -23
  28. package/dist/cjs/scripts/addStandardJob-9.js.map +1 -1
  29. package/dist/cjs/scripts/changePriority-7.js +5 -5
  30. package/dist/cjs/scripts/cleanJobsInSet-3.js +5 -5
  31. package/dist/cjs/scripts/drain-5.js +5 -5
  32. package/dist/cjs/scripts/{getRateLimitTtl-1.js → getRateLimitTtl-2.js} +7 -2
  33. package/dist/cjs/scripts/getRateLimitTtl-2.js.map +1 -0
  34. package/dist/cjs/scripts/index.js +1 -1
  35. package/dist/cjs/scripts/moveJobFromActiveToWait-9.js +6 -6
  36. package/dist/cjs/scripts/moveJobsToWait-8.js +5 -5
  37. package/dist/cjs/scripts/moveStalledJobsToWait-8.js +9 -9
  38. package/dist/cjs/scripts/moveToActive-11.js +13 -12
  39. package/dist/cjs/scripts/moveToActive-11.js.map +1 -1
  40. package/dist/cjs/scripts/moveToDelayed-8.js +1 -1
  41. package/dist/cjs/scripts/moveToFinished-14.js +16 -15
  42. package/dist/cjs/scripts/moveToFinished-14.js.map +1 -1
  43. package/dist/cjs/scripts/obliterate-2.js +5 -5
  44. package/dist/cjs/scripts/promote-9.js +5 -5
  45. package/dist/cjs/scripts/removeChildDependency-1.js +5 -5
  46. package/dist/cjs/scripts/removeJob-2.js +5 -5
  47. package/dist/cjs/scripts/removeUnprocessedChildren-2.js +5 -5
  48. package/dist/cjs/scripts/reprocessJob-8.js +5 -5
  49. package/dist/cjs/scripts/retryJob-11.js +5 -5
  50. package/dist/cjs/scripts/updateJobScheduler-12.js +5 -5
  51. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  52. package/dist/cjs/version.js +1 -1
  53. package/dist/esm/classes/child-pool.js +8 -1
  54. package/dist/esm/classes/child-pool.js.map +1 -1
  55. package/dist/esm/classes/queue.d.ts +6 -0
  56. package/dist/esm/classes/queue.js +9 -0
  57. package/dist/esm/classes/queue.js.map +1 -1
  58. package/dist/esm/classes/scripts.js +4 -1
  59. package/dist/esm/classes/scripts.js.map +1 -1
  60. package/dist/esm/classes/worker.d.ts +1 -0
  61. package/dist/esm/classes/worker.js +42 -30
  62. package/dist/esm/classes/worker.js.map +1 -1
  63. package/dist/esm/commands/changePriority-7.lua +1 -1
  64. package/dist/esm/commands/{getRateLimitTtl-1.lua → getRateLimitTtl-2.lua} +6 -0
  65. package/dist/esm/commands/includes/deduplicateJob.lua +53 -20
  66. package/dist/esm/commands/includes/getTargetQueueList.lua +5 -5
  67. package/dist/esm/commands/includes/prepareJobForProcessing.lua +2 -4
  68. package/dist/esm/commands/moveJobFromActiveToWait-9.lua +1 -1
  69. package/dist/esm/commands/moveStalledJobsToWait-8.lua +0 -1
  70. package/dist/esm/commands/moveToActive-11.lua +7 -4
  71. package/dist/esm/commands/moveToDelayed-8.lua +2 -1
  72. package/dist/esm/commands/moveToFinished-14.lua +10 -7
  73. package/dist/esm/interfaces/base-job-options.d.ts +1 -1
  74. package/dist/esm/interfaces/worker-options.d.ts +8 -0
  75. package/dist/esm/scripts/addDelayedJob-6.js +52 -23
  76. package/dist/esm/scripts/addDelayedJob-6.js.map +1 -1
  77. package/dist/esm/scripts/addJobScheduler-11.js +5 -5
  78. package/dist/esm/scripts/addParentJob-5.js +52 -23
  79. package/dist/esm/scripts/addParentJob-5.js.map +1 -1
  80. package/dist/esm/scripts/addPrioritizedJob-9.js +52 -23
  81. package/dist/esm/scripts/addPrioritizedJob-9.js.map +1 -1
  82. package/dist/esm/scripts/addRepeatableJob-2.js +5 -5
  83. package/dist/esm/scripts/addStandardJob-9.js +52 -23
  84. package/dist/esm/scripts/addStandardJob-9.js.map +1 -1
  85. package/dist/esm/scripts/changePriority-7.js +5 -5
  86. package/dist/esm/scripts/cleanJobsInSet-3.js +5 -5
  87. package/dist/esm/scripts/drain-5.js +5 -5
  88. package/dist/esm/scripts/{getRateLimitTtl-1.js → getRateLimitTtl-2.js} +7 -2
  89. package/dist/esm/scripts/getRateLimitTtl-2.js.map +1 -0
  90. package/dist/esm/scripts/index.d.ts +1 -1
  91. package/dist/esm/scripts/index.js +1 -1
  92. package/dist/esm/scripts/moveJobFromActiveToWait-9.js +6 -6
  93. package/dist/esm/scripts/moveJobsToWait-8.js +5 -5
  94. package/dist/esm/scripts/moveStalledJobsToWait-8.js +9 -9
  95. package/dist/esm/scripts/moveToActive-11.js +13 -12
  96. package/dist/esm/scripts/moveToActive-11.js.map +1 -1
  97. package/dist/esm/scripts/moveToDelayed-8.js +1 -1
  98. package/dist/esm/scripts/moveToFinished-14.js +16 -15
  99. package/dist/esm/scripts/moveToFinished-14.js.map +1 -1
  100. package/dist/esm/scripts/obliterate-2.js +5 -5
  101. package/dist/esm/scripts/promote-9.js +5 -5
  102. package/dist/esm/scripts/removeChildDependency-1.js +5 -5
  103. package/dist/esm/scripts/removeJob-2.js +5 -5
  104. package/dist/esm/scripts/removeUnprocessedChildren-2.js +5 -5
  105. package/dist/esm/scripts/reprocessJob-8.js +5 -5
  106. package/dist/esm/scripts/retryJob-11.js +5 -5
  107. package/dist/esm/scripts/updateJobScheduler-12.js +5 -5
  108. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  109. package/dist/esm/version.d.ts +1 -1
  110. package/dist/esm/version.js +1 -1
  111. package/package.json +1 -1
  112. package/dist/cjs/scripts/getRateLimitTtl-1.js.map +0 -1
  113. package/dist/esm/scripts/getRateLimitTtl-1.js.map +0 -1
  114. /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'] and ttl and ttl > 0 then
12
- local currentDebounceJobId = rcall('GET', deduplicationKey)
13
- if currentDebounceJobId then
14
- if rcall("ZREM", delayedKey, currentDebounceJobId) > 0 then
15
- removeJobKeys(prefix .. currentDebounceJobId)
16
- rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDebounceJobId,
17
- "prev", "delayed")
18
-
19
- if deduplicationOpts['extend'] then
20
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
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
- rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
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
- return currentDebounceJobId
48
+ rcall('SET', deduplicationKey, jobId, 'PX', ttl)
49
+ return
30
50
  end
31
51
  else
32
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
33
- return
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
 
@@ -10,7 +10,7 @@
10
10
  KEYS[6] limiter key
11
11
  KEYS[7] prioritized key
12
12
  KEYS[8] marker key
13
- KEYS[9] event key
13
+ KEYS[9] event key
14
14
 
15
15
  ARGV[1] job id
16
16
  ARGV[2] lock token
@@ -24,7 +24,6 @@ local rcall = redis.call
24
24
  -- Includes
25
25
  --- @include "includes/addJobInTargetList"
26
26
  --- @include "includes/batches"
27
- --- @include "includes/getTargetQueueList"
28
27
  --- @include "includes/moveJobToWait"
29
28
  --- @include "includes/trimEvents"
30
29
 
@@ -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], activeKey, waitKey, KEYS[8])
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], KEYS[1], KEYS[8])
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, markerKey,
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, markerKey,
254
- opts)
256
+ return prepareJobForProcessing(prefix, KEYS[6], eventStreamKey, jobId, timestamp, maxJobs,
257
+ limiterDuration, markerKey, opts)
255
258
  end
256
259
  end
257
260
 
@@ -24,7 +24,7 @@ export interface DefaultJobOptions {
24
24
  delay?: number;
25
25
  /**
26
26
  * The total number of attempts to try the job until it completes.
27
- * @defaultValue 0
27
+ * @defaultValue 1
28
28
  */
29
29
  attempts?: number;
30
30
  /**
@@ -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'] and ttl and ttl > 0 then
129
- local currentDebounceJobId = rcall('GET', deduplicationKey)
130
- if currentDebounceJobId then
131
- if rcall("ZREM", delayedKey, currentDebounceJobId) > 0 then
132
- removeJobKeys(prefix .. currentDebounceJobId)
133
- rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDebounceJobId,
134
- "prev", "delayed")
135
- if deduplicationOpts['extend'] then
136
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
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
- rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
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
- return currentDebounceJobId
160
+ rcall('SET', deduplicationKey, jobId, 'PX', ttl)
161
+ return
145
162
  end
146
163
  else
147
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
148
- return
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0bf,CAAC;AACF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
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'] and ttl and ttl > 0 then
62
- local currentDebounceJobId = rcall('GET', deduplicationKey)
63
- if currentDebounceJobId then
64
- if rcall("ZREM", delayedKey, currentDebounceJobId) > 0 then
65
- removeJobKeys(prefix .. currentDebounceJobId)
66
- rcall("XADD", eventsKey, "*", "event", "removed", "jobId", currentDebounceJobId,
67
- "prev", "delayed")
68
- if deduplicationOpts['extend'] then
69
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
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
- rcall('SET', deduplicationKey, jobId, 'KEEPTTL')
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
- return currentDebounceJobId
93
+ rcall('SET', deduplicationKey, jobId, 'PX', ttl)
94
+ return
78
95
  end
79
96
  else
80
- rcall('SET', deduplicationKey, jobId, 'PX', ttl)
81
- return
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkZf,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,cAAc;IACpB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
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"}