bullmq 1.59.0 → 1.59.1
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/bullmq.d.ts +1839 -0
- package/dist/{commands → cjs/commands}/addJob-9.lua +0 -0
- package/dist/{commands → cjs/commands}/changeDelay-4.lua +0 -0
- package/dist/{commands → cjs/commands}/cleanJobsInSet-2.lua +0 -0
- package/dist/{commands → cjs/commands}/drain-4.lua +0 -0
- package/dist/{commands → cjs/commands}/extendLock-2.lua +0 -0
- package/dist/{commands → cjs/commands}/getState-7.lua +0 -0
- package/dist/{commands → cjs/commands}/getStateV2-7.lua +0 -0
- package/dist/{commands → cjs/commands}/includes/destructureJobKey.lua +0 -0
- package/dist/{commands → cjs/commands}/includes/updateParentDepsIfNeeded.lua +0 -0
- package/dist/{commands → cjs/commands}/isFinished-3.lua +0 -0
- package/dist/{commands → cjs/commands}/isJobInList-1.lua +0 -0
- package/dist/{commands → cjs/commands}/moveStalledJobsToWait-8.lua +0 -0
- package/dist/{commands → cjs/commands}/moveToActive-8.lua +0 -0
- package/dist/{commands → cjs/commands}/moveToDelayed-5.lua +0 -0
- package/dist/{commands → cjs/commands}/moveToFinished-8.lua +0 -0
- package/dist/{commands → cjs/commands}/moveToWaitingChildren-4.lua +0 -0
- package/dist/{commands → cjs/commands}/obliterate-2.lua +0 -0
- package/dist/{commands → cjs/commands}/pause-4.lua +0 -0
- package/dist/{commands → cjs/commands}/promote-5.lua +0 -0
- package/dist/{commands → cjs/commands}/releaseLock-1.lua +0 -0
- package/dist/{commands → cjs/commands}/removeJob-1.lua +0 -0
- package/dist/{commands → cjs/commands}/removeRepeatable-2.lua +0 -0
- package/dist/{commands → cjs/commands}/reprocessJob-4.lua +0 -0
- package/dist/{commands → cjs/commands}/retryJob-4.lua +0 -0
- package/dist/{commands → cjs/commands}/takeLock-1.lua +0 -0
- package/dist/{commands → cjs/commands}/updateDelaySet-7.lua +0 -0
- package/dist/{commands → cjs/commands}/updateProgress-2.lua +0 -0
- package/dist/esm/commands/addJob-9.lua +179 -0
- package/dist/esm/commands/changeDelay-4.lua +41 -0
- package/dist/esm/commands/cleanJobsInSet-2.lua +65 -0
- package/dist/esm/commands/drain-4.lua +36 -0
- package/dist/esm/commands/extendLock-2.lua +23 -0
- package/dist/esm/commands/getState-7.lua +63 -0
- package/dist/esm/commands/getStateV2-7.lua +51 -0
- package/dist/esm/commands/includes/destructureJobKey.lua +12 -0
- package/dist/esm/commands/includes/updateParentDepsIfNeeded.lua +19 -0
- package/dist/esm/commands/isFinished-3.lua +48 -0
- package/dist/esm/commands/isJobInList-1.lua +20 -0
- package/dist/esm/commands/moveStalledJobsToWait-8.lua +112 -0
- package/dist/esm/commands/moveToActive-8.lua +100 -0
- package/dist/esm/commands/moveToDelayed-5.lua +45 -0
- package/dist/esm/commands/moveToFinished-8.lua +159 -0
- package/dist/esm/commands/moveToWaitingChildren-4.lua +60 -0
- package/dist/esm/commands/obliterate-2.lua +129 -0
- package/dist/esm/commands/pause-4.lua +27 -0
- package/dist/esm/commands/promote-5.lua +54 -0
- package/dist/esm/commands/releaseLock-1.lua +19 -0
- package/dist/esm/commands/removeJob-1.lua +115 -0
- package/dist/esm/commands/removeRepeatable-2.lua +23 -0
- package/dist/esm/commands/reprocessJob-4.lua +32 -0
- package/dist/esm/commands/retryJob-4.lua +34 -0
- package/dist/esm/commands/takeLock-1.lua +17 -0
- package/dist/esm/commands/updateDelaySet-7.lua +73 -0
- package/dist/esm/commands/updateProgress-2.lua +15 -0
- package/package.json +4 -4
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,179 @@
|
|
1
|
+
--[[
|
2
|
+
Adds a job to the queue by doing the following:
|
3
|
+
- Increases the job counter if needed.
|
4
|
+
- Creates a new job key with the job data.
|
5
|
+
|
6
|
+
- if delayed:
|
7
|
+
- computes timestamp.
|
8
|
+
- adds to delayed zset.
|
9
|
+
- Emits a global event 'delayed' if the job is delayed.
|
10
|
+
- if not delayed
|
11
|
+
- Adds the jobId to the wait/paused list in one of three ways:
|
12
|
+
- LIFO
|
13
|
+
- FIFO
|
14
|
+
- prioritized.
|
15
|
+
- Adds the job to the "added" list so that workers gets notified.
|
16
|
+
|
17
|
+
Input:
|
18
|
+
KEYS[1] 'wait',
|
19
|
+
KEYS[2] 'paused'
|
20
|
+
KEYS[3] 'meta'
|
21
|
+
KEYS[4] 'id'
|
22
|
+
KEYS[5] 'delayed'
|
23
|
+
KEYS[6] 'priority'
|
24
|
+
KEYS[7] 'completed'
|
25
|
+
KEYS[8] events stream key
|
26
|
+
KEYS[9] delay stream key
|
27
|
+
|
28
|
+
ARGV[1] msgpacked arguments array
|
29
|
+
[1] key prefix,
|
30
|
+
[2] custom id (will not generate one automatically)
|
31
|
+
[3] name
|
32
|
+
[4] timestamp
|
33
|
+
[5] parentKey?
|
34
|
+
[6] waitChildrenKey key.
|
35
|
+
[7] parent dependencies key.
|
36
|
+
|
37
|
+
ARGV[2] Json stringified job data
|
38
|
+
ARGV[3] msgpacked options
|
39
|
+
|
40
|
+
Output:
|
41
|
+
jobId - OK
|
42
|
+
-5 - Missing parent key
|
43
|
+
]]
|
44
|
+
local jobId
|
45
|
+
local jobIdKey
|
46
|
+
local rcall = redis.call
|
47
|
+
|
48
|
+
local args = cmsgpack.unpack(ARGV[1])
|
49
|
+
|
50
|
+
local data = ARGV[2]
|
51
|
+
local opts = cmsgpack.unpack(ARGV[3])
|
52
|
+
|
53
|
+
local parentKey = args[5]
|
54
|
+
local parentId
|
55
|
+
local parentQueueKey
|
56
|
+
local parentData
|
57
|
+
|
58
|
+
-- Includes
|
59
|
+
--- @include "includes/destructureJobKey"
|
60
|
+
|
61
|
+
if parentKey ~= nil then
|
62
|
+
if rcall("EXISTS", parentKey) ~= 1 then
|
63
|
+
return -5
|
64
|
+
end
|
65
|
+
|
66
|
+
parentId = getJobIdFromKey(parentKey)
|
67
|
+
parentQueueKey = getJobKeyPrefix(parentKey, ":" .. parentId)
|
68
|
+
local parent = {}
|
69
|
+
parent['id'] = parentId
|
70
|
+
parent['queueKey'] = parentQueueKey
|
71
|
+
parentData = cjson.encode(parent)
|
72
|
+
end
|
73
|
+
|
74
|
+
local jobCounter = rcall("INCR", KEYS[4])
|
75
|
+
|
76
|
+
-- Includes
|
77
|
+
--- @include "includes/updateParentDepsIfNeeded"
|
78
|
+
|
79
|
+
local parentDependenciesKey = args[7]
|
80
|
+
if args[2] == "" then
|
81
|
+
jobId = jobCounter
|
82
|
+
jobIdKey = args[1] .. jobId
|
83
|
+
else
|
84
|
+
jobId = args[2]
|
85
|
+
jobIdKey = args[1] .. jobId
|
86
|
+
if rcall("EXISTS", jobIdKey) == 1 then
|
87
|
+
if parentKey ~= nil then
|
88
|
+
if rcall("ZSCORE", KEYS[7], jobId) ~= false then
|
89
|
+
local returnvalue = rcall("HGET", jobIdKey, "returnvalue")
|
90
|
+
updateParentDepsIfNeeded(parentKey, parentQueueKey, parentDependenciesKey, parentId, jobIdKey, returnvalue)
|
91
|
+
else
|
92
|
+
if parentDependenciesKey ~= nil then
|
93
|
+
rcall("SADD", parentDependenciesKey, jobIdKey)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
rcall("HMSET", jobIdKey, "parentKey", parentKey, "parent", parentData)
|
97
|
+
end
|
98
|
+
return jobId .. "" -- convert to string
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
-- Store the job.
|
103
|
+
local jsonOpts = cjson.encode(opts)
|
104
|
+
local delay = opts['delay'] or 0
|
105
|
+
local priority = opts['priority'] or 0
|
106
|
+
local timestamp = args[4]
|
107
|
+
|
108
|
+
if parentKey ~= nil then
|
109
|
+
rcall("HMSET", jobIdKey, "name", args[3], "data", ARGV[2], "opts", jsonOpts,
|
110
|
+
"timestamp", timestamp, "delay", delay, "priority", priority, "parentKey", parentKey, "parent", parentData)
|
111
|
+
else
|
112
|
+
rcall("HMSET", jobIdKey, "name", args[3], "data", ARGV[2], "opts", jsonOpts,
|
113
|
+
"timestamp", timestamp, "delay", delay, "priority", priority )
|
114
|
+
end
|
115
|
+
|
116
|
+
-- TODO: do not send data and opts to the event added (for performance reasons).
|
117
|
+
rcall("XADD", KEYS[8], "*", "event", "added", "jobId", jobId, "name", args[3], "data", ARGV[2], "opts", jsonOpts)
|
118
|
+
|
119
|
+
-- Check if job is delayed
|
120
|
+
local delayedTimestamp = (delay > 0 and (timestamp + delay)) or 0
|
121
|
+
|
122
|
+
-- Check if job is a parent, if so add to the parents set
|
123
|
+
local waitChildrenKey = args[6]
|
124
|
+
if waitChildrenKey ~= nil then
|
125
|
+
rcall("ZADD", waitChildrenKey, timestamp, jobId)
|
126
|
+
rcall("XADD", KEYS[8], "*", "event", "waiting-children", "jobId", jobId)
|
127
|
+
elseif (delayedTimestamp ~= 0) then
|
128
|
+
local timestamp = delayedTimestamp * 0x1000 + bit.band(jobCounter, 0xfff)
|
129
|
+
rcall("ZADD", KEYS[5], timestamp, jobId)
|
130
|
+
rcall("XADD", KEYS[8], "*", "event", "delayed", "jobId", jobId, "delay",
|
131
|
+
delayedTimestamp)
|
132
|
+
rcall("XADD", KEYS[9], "*", "nextTimestamp", delayedTimestamp)
|
133
|
+
else
|
134
|
+
local target
|
135
|
+
|
136
|
+
-- We check for the meta.paused key to decide if we are paused or not
|
137
|
+
-- (since an empty list and !EXISTS are not really the same)
|
138
|
+
local paused
|
139
|
+
if rcall("HEXISTS", KEYS[3], "paused") ~= 1 then
|
140
|
+
target = KEYS[1]
|
141
|
+
paused = false
|
142
|
+
else
|
143
|
+
target = KEYS[2]
|
144
|
+
paused = true
|
145
|
+
end
|
146
|
+
|
147
|
+
-- Standard or priority add
|
148
|
+
if priority == 0 then
|
149
|
+
-- LIFO or FIFO
|
150
|
+
local pushCmd = opts['lifo'] and 'RPUSH' or 'LPUSH';
|
151
|
+
rcall(pushCmd, target, jobId)
|
152
|
+
else
|
153
|
+
-- Priority add
|
154
|
+
rcall("ZADD", KEYS[6], priority, jobId)
|
155
|
+
local count = rcall("ZCOUNT", KEYS[6], 0, priority)
|
156
|
+
|
157
|
+
local len = rcall("LLEN", target)
|
158
|
+
local id = rcall("LINDEX", target, len - (count - 1))
|
159
|
+
if id then
|
160
|
+
rcall("LINSERT", target, "BEFORE", id, jobId)
|
161
|
+
else
|
162
|
+
rcall("RPUSH", target, jobId)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
-- Emit waiting event
|
166
|
+
rcall("XADD", KEYS[8], "*", "event", "waiting", "jobId", jobId)
|
167
|
+
end
|
168
|
+
|
169
|
+
-- Check if this job is a child of another job, if so add it to the parents dependencies
|
170
|
+
-- TODO: Should not be possible to add a child job to a parent that is not in the "waiting-children" status.
|
171
|
+
-- fail in this case.
|
172
|
+
if parentDependenciesKey ~= nil then
|
173
|
+
rcall("SADD", parentDependenciesKey, jobIdKey)
|
174
|
+
end
|
175
|
+
|
176
|
+
local maxEvents = rcall("HGET", KEYS[3], "opts.maxLenEvents")
|
177
|
+
if (maxEvents) then rcall("XTRIM", KEYS[8], "MAXLEN", "~", maxEvents) end
|
178
|
+
|
179
|
+
return jobId .. "" -- convert to string
|
@@ -0,0 +1,41 @@
|
|
1
|
+
--[[
|
2
|
+
Change job delay when it is in delayed set.
|
3
|
+
Input:
|
4
|
+
KEYS[1] delayed key
|
5
|
+
KEYS[2] job key
|
6
|
+
KEYS[3] events stream
|
7
|
+
KEYS[4] delayed stream
|
8
|
+
|
9
|
+
ARGV[1] delayedTimestamp
|
10
|
+
ARGV[2] the id of the job
|
11
|
+
Output:
|
12
|
+
0 - OK
|
13
|
+
-1 - Missing job.
|
14
|
+
-3 - Job not in delayed set.
|
15
|
+
|
16
|
+
Events:
|
17
|
+
- delayed key.
|
18
|
+
]]
|
19
|
+
local rcall = redis.call
|
20
|
+
|
21
|
+
if rcall("EXISTS", KEYS[2]) == 1 then
|
22
|
+
|
23
|
+
local jobId = ARGV[2]
|
24
|
+
local score = tonumber(ARGV[1])
|
25
|
+
local delayedTimestamp = (score / 0x1000)
|
26
|
+
|
27
|
+
local numRemovedElements = rcall("ZREM", KEYS[1], jobId)
|
28
|
+
|
29
|
+
if (numRemovedElements < 1) then
|
30
|
+
return -3
|
31
|
+
end
|
32
|
+
|
33
|
+
rcall("ZADD", KEYS[1], score, jobId)
|
34
|
+
|
35
|
+
rcall("XADD", KEYS[3], "*", "event", "delayed", "jobId", jobId, "delay", delayedTimestamp);
|
36
|
+
rcall("XADD", KEYS[4], "*", "nextTimestamp", delayedTimestamp);
|
37
|
+
|
38
|
+
return 0
|
39
|
+
else
|
40
|
+
return -1
|
41
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
--[[
|
2
|
+
Remove jobs from the specific set.
|
3
|
+
|
4
|
+
Input:
|
5
|
+
KEYS[1] set key,
|
6
|
+
KEYS[2] events stream key
|
7
|
+
|
8
|
+
ARGV[1] jobId
|
9
|
+
ARGV[2] timestamp
|
10
|
+
ARGV[3] limit the number of jobs to be removed. 0 is unlimited
|
11
|
+
ARGV[4] set name, can be any of 'wait', 'active', 'paused', 'delayed', 'completed', or 'failed'
|
12
|
+
]]
|
13
|
+
local rcall = redis.call
|
14
|
+
local command = "ZRANGE"
|
15
|
+
local isList = false
|
16
|
+
|
17
|
+
if ARGV[4] == "wait" or ARGV[4] == "active" or ARGV[4] == "paused" then
|
18
|
+
command = "LRANGE"
|
19
|
+
isList = true
|
20
|
+
end
|
21
|
+
|
22
|
+
local rangeStart = 0
|
23
|
+
local rangeEnd = -1
|
24
|
+
|
25
|
+
local limit = tonumber(ARGV[3])
|
26
|
+
|
27
|
+
-- If we're only deleting _n_ items, avoid retrieving all items
|
28
|
+
-- for faster performance
|
29
|
+
--
|
30
|
+
-- Start from the tail of the list, since that's where oldest elements
|
31
|
+
-- are generally added for FIFO lists
|
32
|
+
if limit > 0 then
|
33
|
+
rangeStart = -1 - limit + 1
|
34
|
+
rangeEnd = -1
|
35
|
+
end
|
36
|
+
|
37
|
+
local jobs = rcall(command, KEYS[1], rangeStart, rangeEnd)
|
38
|
+
local deleted = {}
|
39
|
+
local deletedCount = 0
|
40
|
+
local jobTS
|
41
|
+
for _, job in ipairs(jobs) do
|
42
|
+
if limit > 0 and deletedCount >= limit then
|
43
|
+
break
|
44
|
+
end
|
45
|
+
|
46
|
+
local jobKey = ARGV[1] .. job
|
47
|
+
if (rcall("EXISTS", jobKey .. ":lock") == 0) then
|
48
|
+
jobTS = rcall("HGET", jobKey, "timestamp")
|
49
|
+
if (not jobTS or jobTS < ARGV[2]) then
|
50
|
+
if isList then
|
51
|
+
rcall("LREM", KEYS[1], 0, job)
|
52
|
+
else
|
53
|
+
rcall("ZREM", KEYS[1], job)
|
54
|
+
end
|
55
|
+
rcall("DEL", jobKey)
|
56
|
+
rcall("DEL", jobKey .. ":logs")
|
57
|
+
deletedCount = deletedCount + 1
|
58
|
+
table.insert(deleted, job)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
rcall("XADD", KEYS[2], "*", "event", "cleaned", "count", deletedCount)
|
64
|
+
|
65
|
+
return deleted
|
@@ -0,0 +1,36 @@
|
|
1
|
+
--[[
|
2
|
+
Drains the queue, removes all jobs that are waiting
|
3
|
+
or delayed, but not active, completed or failed
|
4
|
+
|
5
|
+
Input:
|
6
|
+
KEYS[1] 'wait',
|
7
|
+
KEYS[2] 'paused'
|
8
|
+
KEYS[3] 'delayed'
|
9
|
+
KEYS[4] 'priority'
|
10
|
+
|
11
|
+
ARGV[1] queue key prefix
|
12
|
+
]]
|
13
|
+
local rcall = redis.call
|
14
|
+
local queueBaseKey = ARGV[1]
|
15
|
+
|
16
|
+
local function removeJobs (list)
|
17
|
+
for _, id in ipairs(list) do
|
18
|
+
rcall("DEL", queueBaseKey .. id)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
local wait_ids = rcall("LRANGE", KEYS[1] , 0, -1)
|
23
|
+
local paused_ids = rcall("LRANGE", KEYS[2] , 0, -1)
|
24
|
+
|
25
|
+
removeJobs(wait_ids)
|
26
|
+
removeJobs(paused_ids)
|
27
|
+
|
28
|
+
if KEYS[3] ~= "" then
|
29
|
+
local delayed_ids = rcall("ZRANGE", KEYS[3] , 0, -1)
|
30
|
+
removeJobs(delayed_ids)
|
31
|
+
rcall("DEL", KEYS[3])
|
32
|
+
end
|
33
|
+
|
34
|
+
rcall("DEL", KEYS[1])
|
35
|
+
rcall("DEL", KEYS[2])
|
36
|
+
rcall("DEL", KEYS[4])
|
@@ -0,0 +1,23 @@
|
|
1
|
+
--[[
|
2
|
+
Extend lock and removes the job from the stalled set.
|
3
|
+
|
4
|
+
Input:
|
5
|
+
KEYS[1] 'lock',
|
6
|
+
KEYS[2] 'stalled'
|
7
|
+
|
8
|
+
ARGV[1] token
|
9
|
+
ARGV[2] lock duration in milliseconds
|
10
|
+
ARGV[3] jobid
|
11
|
+
|
12
|
+
Output:
|
13
|
+
"1" if lock extented succesfully.
|
14
|
+
]]
|
15
|
+
local rcall = redis.call
|
16
|
+
if rcall("GET", KEYS[1]) == ARGV[1] then
|
17
|
+
-- if rcall("SET", KEYS[1], ARGV[1], "PX", ARGV[2], "XX") then
|
18
|
+
if rcall("SET", KEYS[1], ARGV[1], "PX", ARGV[2]) then
|
19
|
+
rcall("SREM", KEYS[2], ARGV[3])
|
20
|
+
return 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return 0
|
@@ -0,0 +1,63 @@
|
|
1
|
+
--[[
|
2
|
+
Get a job state
|
3
|
+
|
4
|
+
Input:
|
5
|
+
KEYS[1] 'completed' key,
|
6
|
+
KEYS[2] 'failed' key
|
7
|
+
KEYS[3] 'delayed' key
|
8
|
+
KEYS[4] 'active' key
|
9
|
+
KEYS[5] 'wait' key
|
10
|
+
KEYS[6] 'paused' key
|
11
|
+
KEYS[7] waitChildrenKey key
|
12
|
+
|
13
|
+
ARGV[1] job id
|
14
|
+
Output:
|
15
|
+
'completed'
|
16
|
+
'failed'
|
17
|
+
'delayed'
|
18
|
+
'active'
|
19
|
+
'waiting'
|
20
|
+
'waiting-children'
|
21
|
+
'unknown'
|
22
|
+
]]
|
23
|
+
if redis.call("ZSCORE", KEYS[1], ARGV[1]) ~= false then
|
24
|
+
return "completed"
|
25
|
+
end
|
26
|
+
|
27
|
+
if redis.call("ZSCORE", KEYS[2], ARGV[1]) ~= false then
|
28
|
+
return "failed"
|
29
|
+
end
|
30
|
+
|
31
|
+
if redis.call("ZSCORE", KEYS[3], ARGV[1]) ~= false then
|
32
|
+
return "delayed"
|
33
|
+
end
|
34
|
+
|
35
|
+
local function item_in_list (list, item)
|
36
|
+
for _, v in pairs(list) do
|
37
|
+
if v == item then
|
38
|
+
return 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return nil
|
42
|
+
end
|
43
|
+
|
44
|
+
local active_items = redis.call("LRANGE", KEYS[4] , 0, -1)
|
45
|
+
if item_in_list(active_items, ARGV[1]) ~= nil then
|
46
|
+
return "active"
|
47
|
+
end
|
48
|
+
|
49
|
+
local wait_items = redis.call("LRANGE", KEYS[5] , 0, -1)
|
50
|
+
if item_in_list(wait_items, ARGV[1]) ~= nil then
|
51
|
+
return "waiting"
|
52
|
+
end
|
53
|
+
|
54
|
+
local paused_items = redis.call("LRANGE", KEYS[6] , 0, -1)
|
55
|
+
if item_in_list(paused_items, ARGV[1]) ~= nil then
|
56
|
+
return "waiting"
|
57
|
+
end
|
58
|
+
|
59
|
+
if redis.call("ZSCORE", KEYS[7], ARGV[1]) ~= false then
|
60
|
+
return "waiting-children"
|
61
|
+
end
|
62
|
+
|
63
|
+
return "unknown"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
--[[
|
2
|
+
Get a job state
|
3
|
+
|
4
|
+
Input:
|
5
|
+
KEYS[1] 'completed' key,
|
6
|
+
KEYS[2] 'failed' key
|
7
|
+
KEYS[3] 'delayed' key
|
8
|
+
KEYS[4] 'active' key
|
9
|
+
KEYS[5] 'wait' key
|
10
|
+
KEYS[6] 'paused' key
|
11
|
+
KEYS[7] waitChildrenKey key
|
12
|
+
|
13
|
+
ARGV[1] job id
|
14
|
+
Output:
|
15
|
+
'completed'
|
16
|
+
'failed'
|
17
|
+
'delayed'
|
18
|
+
'active'
|
19
|
+
'waiting'
|
20
|
+
'waiting-children'
|
21
|
+
'unknown'
|
22
|
+
]]
|
23
|
+
if redis.call("ZSCORE", KEYS[1], ARGV[1]) ~= false then
|
24
|
+
return "completed"
|
25
|
+
end
|
26
|
+
|
27
|
+
if redis.call("ZSCORE", KEYS[2], ARGV[1]) ~= false then
|
28
|
+
return "failed"
|
29
|
+
end
|
30
|
+
|
31
|
+
if redis.call("ZSCORE", KEYS[3], ARGV[1]) ~= false then
|
32
|
+
return "delayed"
|
33
|
+
end
|
34
|
+
|
35
|
+
if redis.call("LPOS", KEYS[4] , ARGV[1]) ~= false then
|
36
|
+
return "active"
|
37
|
+
end
|
38
|
+
|
39
|
+
if redis.call("LPOS", KEYS[5] , ARGV[1]) ~= false then
|
40
|
+
return "waiting"
|
41
|
+
end
|
42
|
+
|
43
|
+
if redis.call("LPOS", KEYS[6] , ARGV[1]) ~= false then
|
44
|
+
return "waiting"
|
45
|
+
end
|
46
|
+
|
47
|
+
if redis.call("ZSCORE", KEYS[7] , ARGV[1]) ~= false then
|
48
|
+
return "waiting-children"
|
49
|
+
end
|
50
|
+
|
51
|
+
return "unknown"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
--[[
|
2
|
+
Functions to destructure job key.
|
3
|
+
Just a bit of warning, these functions may be a bit slow and affect performance significantly.
|
4
|
+
]]
|
5
|
+
|
6
|
+
local getJobIdFromKey = function (jobKey)
|
7
|
+
return string.match(jobKey, ".*:(.*)")
|
8
|
+
end
|
9
|
+
|
10
|
+
local getJobKeyPrefix = function (jobKey, jobId)
|
11
|
+
return string.sub(jobKey, 0, #jobKey - #jobId)
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
--[[
|
2
|
+
Validate and move or add dependencies to parent.
|
3
|
+
]]
|
4
|
+
|
5
|
+
local function updateParentDepsIfNeeded(parentKey, parentQueueKey, parentDependenciesKey, parentId, jobIdKey, returnvalue )
|
6
|
+
local processedSet = parentKey .. ":processed"
|
7
|
+
rcall("HSET", processedSet, jobIdKey, returnvalue)
|
8
|
+
local activeParent = rcall("ZSCORE", parentQueueKey .. ":waiting-children", parentId)
|
9
|
+
if rcall("SCARD", parentDependenciesKey) == 0 and activeParent then
|
10
|
+
rcall("ZREM", parentQueueKey .. ":waiting-children", parentId)
|
11
|
+
if rcall("HEXISTS", parentQueueKey .. ":meta", "paused") ~= 1 then
|
12
|
+
rcall("RPUSH", parentQueueKey .. ":wait", parentId)
|
13
|
+
else
|
14
|
+
rcall("RPUSH", parentQueueKey .. ":paused", parentId)
|
15
|
+
end
|
16
|
+
local parentEventStream = parentQueueKey .. ":events"
|
17
|
+
rcall("XADD", parentEventStream, "*", "event", "active", "jobId", parentId, "prev", "waiting-children")
|
18
|
+
end
|
19
|
+
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,20 @@
|
|
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
|
+
local function item_in_list (list, item)
|
12
|
+
for _, v in pairs(list) do
|
13
|
+
if v == item then
|
14
|
+
return 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
local items = redis.call("LRANGE", KEYS[1] , 0, -1)
|
20
|
+
return item_in_list(items, ARGV[1])
|