bullmq 2.3.1 → 2.3.2

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 (109) hide show
  1. package/dist/cjs/classes/redis-connection.js +1 -1
  2. package/dist/cjs/classes/redis-connection.js.map +1 -1
  3. package/dist/cjs/commands/addJob-8.lua +174 -0
  4. package/dist/cjs/commands/changeDelay-4.lua +43 -0
  5. package/dist/cjs/commands/cleanJobsInSet-2.lua +46 -0
  6. package/dist/cjs/commands/drain-4.lua +25 -0
  7. package/dist/cjs/commands/extendLock-2.lua +23 -0
  8. package/dist/cjs/commands/getState-7.lua +57 -0
  9. package/dist/cjs/commands/getStateV2-7.lua +51 -0
  10. package/dist/cjs/commands/includes/addJobWithPriority.lua +16 -0
  11. package/dist/cjs/commands/includes/batches.lua +18 -0
  12. package/dist/cjs/commands/includes/checkItemInList.lua +12 -0
  13. package/dist/cjs/commands/includes/checkStalledJobs.lua +137 -0
  14. package/dist/cjs/commands/includes/cleanList.lua +50 -0
  15. package/dist/cjs/commands/includes/cleanSet.lua +50 -0
  16. package/dist/cjs/commands/includes/collectMetrics.lua +46 -0
  17. package/dist/cjs/commands/includes/destructureJobKey.lua +12 -0
  18. package/dist/cjs/commands/includes/getNextDelayedTimestamp.lua +13 -0
  19. package/dist/cjs/commands/includes/getTargetQueueList.lua +12 -0
  20. package/dist/cjs/commands/includes/getTimestamp.lua +19 -0
  21. package/dist/cjs/commands/includes/getZSetItems.lua +7 -0
  22. package/dist/cjs/commands/includes/isLocked.lua +31 -0
  23. package/dist/cjs/commands/includes/moveJobFromWaitToActive.lua +84 -0
  24. package/dist/cjs/commands/includes/moveParentFromWaitingChildrenToFailed.lua +28 -0
  25. package/dist/cjs/commands/includes/promoteDelayedJobs.lua +49 -0
  26. package/dist/cjs/commands/includes/removeJob.lua +13 -0
  27. package/dist/cjs/commands/includes/removeJobFromAnyState.lua +26 -0
  28. package/dist/cjs/commands/includes/removeJobs.lua +38 -0
  29. package/dist/cjs/commands/includes/removeJobsByMaxAge.lua +15 -0
  30. package/dist/cjs/commands/includes/removeJobsByMaxCount.lua +15 -0
  31. package/dist/cjs/commands/includes/removeParentDependencyKey.lua +81 -0
  32. package/dist/cjs/commands/includes/trimEvents.lua +12 -0
  33. package/dist/cjs/commands/includes/updateParentDepsIfNeeded.lua +28 -0
  34. package/dist/cjs/commands/isFinished-3.lua +48 -0
  35. package/dist/cjs/commands/isJobInList-1.lua +16 -0
  36. package/dist/cjs/commands/moveStalledJobsToWait-8.lua +24 -0
  37. package/dist/cjs/commands/moveToActive-9.lua +67 -0
  38. package/dist/cjs/commands/moveToDelayed-5.lua +54 -0
  39. package/dist/cjs/commands/moveToFinished-12.lua +201 -0
  40. package/dist/cjs/commands/moveToWaitingChildren-4.lua +62 -0
  41. package/dist/cjs/commands/obliterate-2.lua +94 -0
  42. package/dist/cjs/commands/pause-4.lua +27 -0
  43. package/dist/cjs/commands/promote-6.lua +59 -0
  44. package/dist/cjs/commands/releaseLock-1.lua +19 -0
  45. package/dist/cjs/commands/removeJob-1.lua +72 -0
  46. package/dist/cjs/commands/removeRepeatable-2.lua +32 -0
  47. package/dist/cjs/commands/reprocessJob-4.lua +35 -0
  48. package/dist/cjs/commands/retryJob-6.lua +51 -0
  49. package/dist/cjs/commands/retryJobs-6.lua +53 -0
  50. package/dist/cjs/commands/takeLock-1.lua +17 -0
  51. package/dist/cjs/commands/updateData-1.lua +16 -0
  52. package/dist/cjs/commands/updateProgress-2.lua +22 -0
  53. package/dist/cjs/scripts/moveToFinished-12.js +5 -2
  54. package/dist/cjs/scripts/moveToFinished-12.js.map +1 -1
  55. package/dist/esm/classes/redis-connection.js +1 -1
  56. package/dist/esm/classes/redis-connection.js.map +1 -1
  57. package/dist/esm/commands/addJob-8.lua +174 -0
  58. package/dist/esm/commands/changeDelay-4.lua +43 -0
  59. package/dist/esm/commands/cleanJobsInSet-2.lua +46 -0
  60. package/dist/esm/commands/drain-4.lua +25 -0
  61. package/dist/esm/commands/extendLock-2.lua +23 -0
  62. package/dist/esm/commands/getState-7.lua +57 -0
  63. package/dist/esm/commands/getStateV2-7.lua +51 -0
  64. package/dist/esm/commands/includes/addJobWithPriority.lua +16 -0
  65. package/dist/esm/commands/includes/batches.lua +18 -0
  66. package/dist/esm/commands/includes/checkItemInList.lua +12 -0
  67. package/dist/esm/commands/includes/checkStalledJobs.lua +137 -0
  68. package/dist/esm/commands/includes/cleanList.lua +50 -0
  69. package/dist/esm/commands/includes/cleanSet.lua +50 -0
  70. package/dist/esm/commands/includes/collectMetrics.lua +46 -0
  71. package/dist/esm/commands/includes/destructureJobKey.lua +12 -0
  72. package/dist/esm/commands/includes/getNextDelayedTimestamp.lua +13 -0
  73. package/dist/esm/commands/includes/getTargetQueueList.lua +12 -0
  74. package/dist/esm/commands/includes/getTimestamp.lua +19 -0
  75. package/dist/esm/commands/includes/getZSetItems.lua +7 -0
  76. package/dist/esm/commands/includes/isLocked.lua +31 -0
  77. package/dist/esm/commands/includes/moveJobFromWaitToActive.lua +84 -0
  78. package/dist/esm/commands/includes/moveParentFromWaitingChildrenToFailed.lua +28 -0
  79. package/dist/esm/commands/includes/promoteDelayedJobs.lua +49 -0
  80. package/dist/esm/commands/includes/removeJob.lua +13 -0
  81. package/dist/esm/commands/includes/removeJobFromAnyState.lua +26 -0
  82. package/dist/esm/commands/includes/removeJobs.lua +38 -0
  83. package/dist/esm/commands/includes/removeJobsByMaxAge.lua +15 -0
  84. package/dist/esm/commands/includes/removeJobsByMaxCount.lua +15 -0
  85. package/dist/esm/commands/includes/removeParentDependencyKey.lua +81 -0
  86. package/dist/esm/commands/includes/trimEvents.lua +12 -0
  87. package/dist/esm/commands/includes/updateParentDepsIfNeeded.lua +28 -0
  88. package/dist/esm/commands/isFinished-3.lua +48 -0
  89. package/dist/esm/commands/isJobInList-1.lua +16 -0
  90. package/dist/esm/commands/moveStalledJobsToWait-8.lua +24 -0
  91. package/dist/esm/commands/moveToActive-9.lua +67 -0
  92. package/dist/esm/commands/moveToDelayed-5.lua +54 -0
  93. package/dist/esm/commands/moveToFinished-12.lua +201 -0
  94. package/dist/esm/commands/moveToWaitingChildren-4.lua +62 -0
  95. package/dist/esm/commands/obliterate-2.lua +94 -0
  96. package/dist/esm/commands/pause-4.lua +27 -0
  97. package/dist/esm/commands/promote-6.lua +59 -0
  98. package/dist/esm/commands/releaseLock-1.lua +19 -0
  99. package/dist/esm/commands/removeJob-1.lua +72 -0
  100. package/dist/esm/commands/removeRepeatable-2.lua +32 -0
  101. package/dist/esm/commands/reprocessJob-4.lua +35 -0
  102. package/dist/esm/commands/retryJob-6.lua +51 -0
  103. package/dist/esm/commands/retryJobs-6.lua +53 -0
  104. package/dist/esm/commands/takeLock-1.lua +17 -0
  105. package/dist/esm/commands/updateData-1.lua +16 -0
  106. package/dist/esm/commands/updateProgress-2.lua +22 -0
  107. package/dist/esm/scripts/moveToFinished-12.js +5 -2
  108. package/dist/esm/scripts/moveToFinished-12.js.map +1 -1
  109. package/package.json +2 -2
@@ -0,0 +1,49 @@
1
+ --[[
2
+ Updates the delay set, by moving delayed jobs that should
3
+ be processed now to "wait".
4
+
5
+ Events:
6
+ 'waiting'
7
+ ]]
8
+ local rcall = redis.call
9
+
10
+ -- Includes
11
+ --- @include "addJobWithPriority"
12
+ --- @include "getTargetQueueList"
13
+
14
+ -- Try to get as much as 1000 jobs at once, and returns the nextTimestamp if
15
+ -- there are more delayed jobs to process.
16
+ local function promoteDelayedJobs(delayedKey, waitKey, priorityKey, pausedKey,
17
+ metaKey, eventStreamKey, prefix, timestamp)
18
+ local jobs = rcall("ZRANGEBYSCORE", delayedKey, 0, (timestamp + 1) * 0x1000, "LIMIT", 0, 1000)
19
+
20
+ if (#jobs > 0) then
21
+ rcall("ZREM", delayedKey, unpack(jobs))
22
+
23
+ -- check if we need to use push in paused instead of waiting
24
+ local target = getTargetQueueList(metaKey, waitKey, pausedKey)
25
+
26
+ for _, jobId in ipairs(jobs) do
27
+ local priority =
28
+ tonumber(rcall("HGET", prefix .. jobId, "priority")) or 0
29
+
30
+ if priority == 0 then
31
+ -- LIFO or FIFO
32
+ rcall("LPUSH", target, jobId)
33
+ else
34
+ addJobWithPriority(priorityKey, priority, target, jobId)
35
+ end
36
+
37
+ -- Emit waiting event
38
+ rcall("XADD", eventStreamKey, "*", "event", "waiting", "jobId",
39
+ jobId, "prev", "delayed")
40
+ rcall("HSET", prefix .. jobId, "delay", 0)
41
+ end
42
+ end
43
+
44
+ local nextTimestamp = rcall("ZRANGE", delayedKey, 0, 0, "WITHSCORES")[2]
45
+ if (nextTimestamp ~= nil) then
46
+ nextTimestamp = nextTimestamp / 0x1000
47
+ end
48
+ return nextTimestamp
49
+ end
@@ -0,0 +1,13 @@
1
+ --[[
2
+ Function to remove job.
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "removeParentDependencyKey"
7
+
8
+ local function removeJob(jobId, hard, baseKey)
9
+ local jobKey = baseKey .. jobId
10
+ removeParentDependencyKey(jobKey, hard, nil, baseKey)
11
+ rcall("DEL", jobKey, jobKey .. ':logs',
12
+ jobKey .. ':dependencies', jobKey .. ':processed')
13
+ end
@@ -0,0 +1,26 @@
1
+ --[[
2
+ Function to remove from any state.
3
+
4
+ returns:
5
+ prev state
6
+ ]]
7
+
8
+ local function removeJobFromAnyState( prefix, jobId)
9
+ if rcall("LREM", prefix .. "wait", 0, jobId) == 1 then
10
+ return "wait"
11
+ elseif rcall("LREM", prefix .. "paused", 0, jobId) == 1 then
12
+ return "paused"
13
+ elseif rcall("LREM", prefix .. "active", 0, jobId) == 1 then
14
+ return "active"
15
+ elseif rcall("ZREM", prefix .. "waiting-children", jobId) == 1 then
16
+ return "waiting-children"
17
+ elseif rcall("ZREM", prefix .. "delayed", jobId) == 1 then
18
+ return "delayed"
19
+ elseif rcall("ZREM", prefix .. "completed", jobId) == 1 then
20
+ return "completed"
21
+ elseif rcall("ZREM", prefix .. "failed", jobId) == 1 then
22
+ return "failed"
23
+ end
24
+
25
+ return "unknown"
26
+ end
@@ -0,0 +1,38 @@
1
+ --[[
2
+ Functions to remove jobs.
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "batches"
7
+
8
+ local function getListItems(keyName, max)
9
+ return rcall('LRANGE', keyName, 0, max - 1)
10
+ end
11
+
12
+ --- @include "getZSetItems"
13
+ --- @include "removeJob"
14
+
15
+ local function removeJobs(keys, hard, baseKey, max)
16
+ for i, key in ipairs(keys) do
17
+ removeJob(key, hard, baseKey)
18
+ end
19
+ return max - #keys
20
+ end
21
+
22
+ local function removeListJobs(keyName, hard, baseKey, max)
23
+ local jobs = getListItems(keyName, max)
24
+ local count = removeJobs(jobs, hard, baseKey, max)
25
+ rcall("LTRIM", keyName, #jobs, -1)
26
+ return count
27
+ end
28
+
29
+ local function removeZSetJobs(keyName, hard, baseKey, max)
30
+ local jobs = getZSetItems(keyName, max)
31
+ local count = removeJobs(jobs, hard, baseKey, max)
32
+ if(#jobs > 0) then
33
+ for from, to in batches(#jobs, 7000) do
34
+ rcall("ZREM", keyName, unpack(jobs))
35
+ end
36
+ end
37
+ return count
38
+ end
@@ -0,0 +1,15 @@
1
+ --[[
2
+ Functions to remove jobs by max age.
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "removeJob"
7
+
8
+ local function removeJobsByMaxAge(timestamp, maxAge, targetSet, prefix)
9
+ local start = timestamp - maxAge * 1000
10
+ local jobIds = rcall("ZREVRANGEBYSCORE", targetSet, start, "-inf")
11
+ for i, jobId in ipairs(jobIds) do
12
+ removeJob(jobId, false, prefix)
13
+ end
14
+ rcall("ZREMRANGEBYSCORE", targetSet, "-inf", start)
15
+ end
@@ -0,0 +1,15 @@
1
+ --[[
2
+ Functions to remove jobs by max count.
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "removeJob"
7
+
8
+ local function removeJobsByMaxCount(maxCount, targetSet, prefix)
9
+ local start = maxCount
10
+ local jobIds = rcall("ZREVRANGE", targetSet, start, -1)
11
+ for i, jobId in ipairs(jobIds) do
12
+ removeJob(jobId, false, prefix)
13
+ end
14
+ rcall("ZREMRANGEBYRANK", targetSet, 0, -(maxCount + 1))
15
+ end
@@ -0,0 +1,81 @@
1
+ --[[
2
+ Check if this job has a parent. If so we will just remove it from
3
+ the parent child list, but if it is the last child we should move the parent to "wait/paused"
4
+ which requires code from "moveToFinished"
5
+ ]]
6
+
7
+ --- @include "destructureJobKey"
8
+ --- @include "getTargetQueueList"
9
+
10
+ local function moveParentToWait(parentPrefix, parentId, emitEvent)
11
+ local parentTarget = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "wait", parentPrefix .. "paused")
12
+ rcall("RPUSH", parentTarget, parentId)
13
+
14
+ if emitEvent then
15
+ local parentEventStream = parentPrefix .. "events"
16
+ rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
17
+ end
18
+ end
19
+
20
+ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey)
21
+ if parentKey then
22
+ local parentProcessedKey = parentKey .. ":processed"
23
+ rcall("HDEL", parentProcessedKey, jobKey)
24
+ local parentDependenciesKey = parentKey .. ":dependencies"
25
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
26
+ if result > 0 then
27
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
28
+ if pendingDependencies == 0 then
29
+ local parentId = getJobIdFromKey(parentKey)
30
+ local parentPrefix = getJobKeyPrefix(parentKey, parentId)
31
+
32
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
33
+
34
+ if numRemovedElements == 1 then
35
+ if hard then
36
+ if parentPrefix == baseKey then
37
+ removeParentDependencyKey(parentKey, hard, nil, baseKey)
38
+ rcall("DEL", parentKey, parentKey .. ':logs',
39
+ parentKey .. ':dependencies', parentKey .. ':processed')
40
+ else
41
+ moveParentToWait(parentPrefix, parentId)
42
+ end
43
+ else
44
+ moveParentToWait(parentPrefix, parentId, true)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ else
50
+ local missedParentKey = rcall("HGET", jobKey, "parentKey")
51
+ if( (type(missedParentKey) == "string") and missedParentKey ~= "" and (rcall("EXISTS", missedParentKey) == 1)) then
52
+ local parentProcessedKey = missedParentKey .. ":processed"
53
+ rcall("HDEL", parentProcessedKey, jobKey)
54
+ local parentDependenciesKey = missedParentKey .. ":dependencies"
55
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
56
+ if result > 0 then
57
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
58
+ if pendingDependencies == 0 then
59
+ local parentId = getJobIdFromKey(missedParentKey)
60
+ local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
61
+
62
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
63
+
64
+ if numRemovedElements == 1 then
65
+ if hard then
66
+ if parentPrefix == baseKey then
67
+ removeParentDependencyKey(missedParentKey, hard, nil, baseKey)
68
+ rcall("DEL", missedParentKey, missedParentKey .. ':logs',
69
+ missedParentKey .. ':dependencies', missedParentKey .. ':processed')
70
+ else
71
+ moveParentToWait(parentPrefix, parentId)
72
+ end
73
+ else
74
+ moveParentToWait(parentPrefix, parentId, true)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,12 @@
1
+ --[[
2
+ Function to trim events, default 10000.
3
+ ]]
4
+
5
+ local function trimEvents(metaKey, eventStreamKey)
6
+ local maxEvents = rcall("HGET", metaKey, "opts.maxLenEvents")
7
+ if maxEvents ~= false then
8
+ rcall("XTRIM", eventStreamKey, "MAXLEN", "~", maxEvents)
9
+ else
10
+ rcall("XTRIM", eventStreamKey, "MAXLEN", "~", 10000)
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ --[[
2
+ Validate and move or add dependencies to parent.
3
+ ]]
4
+
5
+ -- Includes
6
+ --- @include "addJobWithPriority"
7
+ --- @include "getTargetQueueList"
8
+
9
+ local function updateParentDepsIfNeeded(parentKey, parentQueueKey, parentDependenciesKey,
10
+ parentId, jobIdKey, returnvalue )
11
+ local processedSet = parentKey .. ":processed"
12
+ rcall("HSET", processedSet, jobIdKey, returnvalue)
13
+ local activeParent = rcall("ZSCORE", parentQueueKey .. ":waiting-children", parentId)
14
+ if rcall("SCARD", parentDependenciesKey) == 0 and activeParent then
15
+ rcall("ZREM", parentQueueKey .. ":waiting-children", parentId)
16
+ local parentTarget = getTargetQueueList(parentQueueKey .. ":meta", parentQueueKey .. ":wait",
17
+ parentQueueKey .. ":paused")
18
+ local priority = tonumber(rcall("HGET", parentKey, "priority"))
19
+ -- Standard or priority add
20
+ if priority == 0 then
21
+ rcall("RPUSH", parentTarget, parentId)
22
+ else
23
+ addJobWithPriority(parentQueueKey .. ":priority", priority, parentTarget, parentId)
24
+ end
25
+
26
+ rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ --[[
2
+ Checks if a job is finished (.i.e. is in the completed or failed set)
3
+
4
+ Input:
5
+ KEYS[1] completed key
6
+ KEYS[2] failed key
7
+ KEYS[3] job key
8
+
9
+ ARGV[1] job id
10
+ ARGV[2] return value?
11
+ Output:
12
+ 0 - Not finished.
13
+ 1 - Completed.
14
+ 2 - Failed.
15
+ -5 - Missing job.
16
+ ]]
17
+ local rcall = redis.call
18
+ if rcall("EXISTS", KEYS[3]) ~= 1 then
19
+ if ARGV[2] == "1" then
20
+
21
+ return {-5,"Missing key for job " .. KEYS[3] .. ". isFinished"}
22
+ end
23
+ return -5
24
+ end
25
+
26
+ if rcall("ZSCORE", KEYS[1], ARGV[1]) ~= false then
27
+ if ARGV[2] == "1" then
28
+ local returnValue = rcall("HGET", KEYS[3], "returnvalue")
29
+
30
+ return {1,returnValue}
31
+ end
32
+ return 1
33
+ end
34
+
35
+ if rcall("ZSCORE", KEYS[2], ARGV[1]) ~= false then
36
+ if ARGV[2] == "1" then
37
+ local failedReason = rcall("HGET", KEYS[3], "failedReason")
38
+
39
+ return {2,failedReason}
40
+ end
41
+ return 2
42
+ end
43
+
44
+ if ARGV[2] == "1" then
45
+ return {0}
46
+ end
47
+
48
+ return 0
@@ -0,0 +1,16 @@
1
+ --[[
2
+ Checks if job is in a given list.
3
+
4
+ Input:
5
+ KEYS[1]
6
+ ARGV[1]
7
+
8
+ Output:
9
+ 1 if element found in the list.
10
+ ]]
11
+
12
+ -- Includes
13
+ --- @include "includes/checkItemInList"
14
+
15
+ local items = redis.call("LRANGE", KEYS[1] , 0, -1)
16
+ return checkItemInList(items, ARGV[1])
@@ -0,0 +1,24 @@
1
+ --[[
2
+ Move stalled jobs to wait.
3
+
4
+ Input:
5
+ KEYS[1] 'stalled' (SET)
6
+ KEYS[2] 'wait', (LIST)
7
+ KEYS[3] 'active', (LIST)
8
+ KEYS[4] 'failed', (ZSET)
9
+ KEYS[5] 'stalled-check', (KEY)
10
+ KEYS[6] 'meta', (KEY)
11
+ KEYS[7] 'paused', (LIST)
12
+ KEYS[8] 'event stream' (STREAM)
13
+
14
+ ARGV[1] Max stalled job count
15
+ ARGV[2] queue.toKey('')
16
+ ARGV[3] timestamp
17
+ ARGV[4] max check time
18
+
19
+ Events:
20
+ 'stalled' with stalled job id.
21
+ ]] -- Includes
22
+ --- @include "includes/checkStalledJobs"
23
+ return checkStalledJobs(KEYS[1], KEYS[2], KEYS[3], KEYS[4], KEYS[5], KEYS[6],
24
+ KEYS[7], KEYS[8], ARGV[1], ARGV[2], ARGV[3], ARGV[4])
@@ -0,0 +1,67 @@
1
+ --[[
2
+ Move next job to be processed to active, lock it and fetch its data. The job
3
+ may be delayed, in that case we need to move it to the delayed set instead.
4
+
5
+ This operation guarantees that the worker owns the job during the lock
6
+ expiration time. The worker is responsible of keeping the lock fresh
7
+ so that no other worker picks this job again.
8
+
9
+ Input:
10
+ KEYS[1] wait key
11
+ KEYS[2] active key
12
+ KEYS[3] priority key
13
+ KEYS[4] stream events key
14
+ KEYS[5] stalled key
15
+
16
+ -- Rate limiting
17
+ KEYS[6] rate limiter key
18
+ KEYS[7] delayed key
19
+
20
+ -- Promote delayed jobs
21
+ KEYS[8] paused key
22
+ KEYS[9] meta key
23
+
24
+ -- Arguments
25
+ ARGV[1] key prefix
26
+ ARGV[2] timestamp
27
+ ARGV[3] optional job ID
28
+ ARGV[4] opts
29
+
30
+ opts - token - lock token
31
+ opts - lockDuration
32
+ opts - limiter
33
+ ]]
34
+ local jobId
35
+ local rcall = redis.call
36
+
37
+ -- Includes
38
+ --- @include "includes/moveJobFromWaitToActive"
39
+ --- @include "includes/getNextDelayedTimestamp"
40
+ --- @include "includes/promoteDelayedJobs"
41
+
42
+ -- Check if there are delayed jobs that we can move to wait.
43
+ promoteDelayedJobs(KEYS[7], KEYS[1], KEYS[3], KEYS[8], KEYS[9], KEYS[4], ARGV[1], ARGV[2])
44
+
45
+ if (ARGV[3] ~= "") then
46
+ jobId = ARGV[3]
47
+ -- clean stalled key
48
+ rcall("SREM", KEYS[5], jobId)
49
+ else
50
+ -- no job ID, try non-blocking move from wait to active
51
+ jobId = rcall("RPOPLPUSH", KEYS[1], KEYS[2])
52
+ end
53
+
54
+ -- If jobId is special ID 0, then there is no job to process
55
+ if jobId == "0" then
56
+ rcall("LREM", KEYS[2], 1, 0)
57
+ elseif jobId then
58
+ local opts = cmsgpack.unpack(ARGV[4])
59
+ -- this script is not really moving, it is preparing the job for processing
60
+ return moveJobFromWaitToActive(KEYS, ARGV[1], jobId, ARGV[2], opts)
61
+ end
62
+
63
+ -- Return the timestamp for the next delayed job if any.
64
+ local nextTimestamp = getNextDelayedTimestamp(KEYS[7])
65
+ if (nextTimestamp ~= nil) then
66
+ return nextTimestamp - tonumber(ARGV[2])
67
+ end
@@ -0,0 +1,54 @@
1
+ --[[
2
+ Moves job from active to delayed set.
3
+
4
+ Input:
5
+ KEYS[1] active key
6
+ KEYS[2] delayed key
7
+ KEYS[3] job key
8
+ KEYS[4] events stream
9
+ KEYS[5] delayed stream
10
+
11
+ ARGV[1] delayedTimestamp
12
+ ARGV[2] the id of the job
13
+ ARGV[3] queue token
14
+
15
+ Output:
16
+ 0 - OK
17
+ -1 - Missing job.
18
+ -3 - Job not in active set.
19
+
20
+ Events:
21
+ - delayed key.
22
+ ]]
23
+ local rcall = redis.call
24
+
25
+ if rcall("EXISTS", KEYS[3]) == 1 then
26
+
27
+ if ARGV[3] ~= "0" then
28
+ local lockKey = KEYS[3] .. ':lock'
29
+ if rcall("GET", lockKey) == ARGV[3] then
30
+ rcall("DEL", lockKey)
31
+ else
32
+ return -2
33
+ end
34
+ end
35
+
36
+ local jobId = ARGV[2]
37
+ local score = tonumber(ARGV[1])
38
+ local delayedTimestamp = (score / 0x1000)
39
+
40
+ local numRemovedElements = rcall("LREM", KEYS[1], -1, jobId)
41
+
42
+ if(numRemovedElements < 1) then
43
+ return -3
44
+ end
45
+
46
+ rcall("ZADD", KEYS[2], score, jobId)
47
+
48
+ rcall("XADD", KEYS[4], "*", "event", "delayed", "jobId", jobId, "delay", delayedTimestamp);
49
+ rcall("XADD", KEYS[5], "*", "nextTimestamp", delayedTimestamp);
50
+
51
+ return 0
52
+ else
53
+ return -1
54
+ end