bullmq 5.34.5 → 5.34.7
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/job-scheduler.js +64 -25
- package/dist/cjs/classes/job-scheduler.js.map +1 -1
- package/dist/cjs/classes/job.js +1 -0
- package/dist/cjs/classes/job.js.map +1 -1
- package/dist/cjs/classes/scripts.js +12 -2
- package/dist/cjs/classes/scripts.js.map +1 -1
- package/dist/cjs/commands/addDelayedJob-6.lua +4 -18
- package/dist/cjs/commands/{addJobScheduler-2.lua → addJobScheduler-6.lua} +44 -15
- package/dist/cjs/commands/includes/addDelayedJob.lua +25 -0
- package/dist/cjs/commands/removeJobScheduler-3.lua +1 -1
- package/dist/cjs/scripts/addDelayedJob-6.js +71 -64
- package/dist/cjs/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/cjs/scripts/{addJobScheduler-2.js → addJobScheduler-6.js} +141 -16
- package/dist/cjs/scripts/addJobScheduler-6.js.map +1 -0
- package/dist/cjs/scripts/index.js +1 -1
- package/dist/cjs/scripts/removeJobScheduler-3.js +1 -1
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/classes/job-scheduler.d.ts +1 -0
- package/dist/esm/classes/job-scheduler.js +64 -25
- package/dist/esm/classes/job-scheduler.js.map +1 -1
- package/dist/esm/classes/job.d.ts +4 -0
- package/dist/esm/classes/job.js +1 -0
- package/dist/esm/classes/job.js.map +1 -1
- package/dist/esm/classes/scripts.d.ts +2 -2
- package/dist/esm/classes/scripts.js +12 -2
- package/dist/esm/classes/scripts.js.map +1 -1
- package/dist/esm/commands/addDelayedJob-6.lua +4 -18
- package/dist/esm/commands/{addJobScheduler-2.lua → addJobScheduler-6.lua} +44 -15
- package/dist/esm/commands/includes/addDelayedJob.lua +25 -0
- package/dist/esm/commands/removeJobScheduler-3.lua +1 -1
- package/dist/esm/scripts/addDelayedJob-6.js +71 -64
- package/dist/esm/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/esm/scripts/{addJobScheduler-2.js → addJobScheduler-6.js} +141 -16
- package/dist/esm/scripts/addJobScheduler-6.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/removeJobScheduler-3.js +1 -1
- 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/addJobScheduler-2.js.map +0 -1
- package/dist/esm/scripts/addJobScheduler-2.js.map +0 -1
- /package/dist/esm/scripts/{addJobScheduler-2.d.ts → addJobScheduler-6.d.ts} +0 -0
@@ -2,8 +2,12 @@
|
|
2
2
|
Adds a job scheduler, i.e. a job factory that creates jobs based on a given schedule (repeat options).
|
3
3
|
|
4
4
|
Input:
|
5
|
-
KEYS[1] '
|
6
|
-
KEYS[2] '
|
5
|
+
KEYS[1] 'marker',
|
6
|
+
KEYS[2] 'meta'
|
7
|
+
KEYS[3] 'id'
|
8
|
+
KEYS[4] 'delayed'
|
9
|
+
KEYS[5] events stream key
|
10
|
+
KEYS[6] 'repeat' key
|
7
11
|
|
8
12
|
ARGV[1] next milliseconds
|
9
13
|
ARGV[2] msgpacked options
|
@@ -14,27 +18,31 @@
|
|
14
18
|
[5] every?
|
15
19
|
ARGV[3] jobs scheduler id
|
16
20
|
ARGV[4] Json stringified template data
|
17
|
-
ARGV[5]
|
18
|
-
ARGV[6]
|
21
|
+
ARGV[5] msgpacked template opts
|
22
|
+
ARGV[6] msgpacked delayed opts
|
23
|
+
ARGV[7] timestamp
|
24
|
+
ARGV[8] prefix key
|
25
|
+
ARGV[9] producer key
|
19
26
|
|
20
27
|
Output:
|
21
|
-
|
28
|
+
next delayed job id - OK
|
22
29
|
]]
|
23
30
|
local rcall = redis.call
|
24
|
-
local repeatKey = KEYS[
|
25
|
-
local delayedKey = KEYS[
|
26
|
-
|
31
|
+
local repeatKey = KEYS[6]
|
32
|
+
local delayedKey = KEYS[4]
|
33
|
+
local timestamp = ARGV[7]
|
27
34
|
local nextMillis = ARGV[1]
|
28
35
|
local jobSchedulerId = ARGV[3]
|
29
36
|
local templateOpts = cmsgpack.unpack(ARGV[5])
|
30
|
-
local prefixKey = ARGV[
|
37
|
+
local prefixKey = ARGV[8]
|
31
38
|
|
32
39
|
-- Includes
|
40
|
+
--- @include "includes/addDelayedJob"
|
41
|
+
--- @include "includes/getOrSetMaxEvents"
|
33
42
|
--- @include "includes/removeJob"
|
34
43
|
|
35
|
-
local function storeRepeatableJob(schedulerId, repeatKey, nextMillis,
|
44
|
+
local function storeRepeatableJob(schedulerId, schedulerKey, repeatKey, nextMillis, opts, templateData, templateOpts)
|
36
45
|
rcall("ZADD", repeatKey, nextMillis, schedulerId)
|
37
|
-
local opts = cmsgpack.unpack(rawOpts)
|
38
46
|
|
39
47
|
local optionalValues = {}
|
40
48
|
if opts['tz'] then
|
@@ -68,17 +76,19 @@ local function storeRepeatableJob(schedulerId, repeatKey, nextMillis, rawOpts, t
|
|
68
76
|
table.insert(optionalValues, templateData)
|
69
77
|
end
|
70
78
|
|
71
|
-
rcall("HMSET",
|
79
|
+
rcall("HMSET", schedulerKey, "name", opts['name'],
|
72
80
|
unpack(optionalValues))
|
73
81
|
end
|
74
82
|
|
83
|
+
local schedulerKey = repeatKey .. ":" .. jobSchedulerId
|
84
|
+
local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
|
85
|
+
local nextDelayedJobKey = schedulerKey .. ":" .. nextMillis
|
86
|
+
|
75
87
|
-- If we are overriding a repeatable job we must delete the delayed job for
|
76
88
|
-- the next iteration.
|
77
89
|
local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
|
78
90
|
if prevMillis ~= false then
|
79
91
|
local delayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
|
80
|
-
local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
|
81
|
-
local nextDelayedJobKey = repeatKey .. ":" .. jobSchedulerId .. ":" .. nextMillis
|
82
92
|
|
83
93
|
if rcall("ZSCORE", delayedKey, delayedJobId) ~= false
|
84
94
|
and (rcall("EXISTS", nextDelayedJobKey) ~= 1
|
@@ -88,4 +98,23 @@ if prevMillis ~= false then
|
|
88
98
|
end
|
89
99
|
end
|
90
100
|
|
91
|
-
|
101
|
+
local schedulerOpts = cmsgpack.unpack(ARGV[2])
|
102
|
+
|
103
|
+
storeRepeatableJob(jobSchedulerId, schedulerKey, repeatKey, nextMillis, schedulerOpts, ARGV[4], templateOpts)
|
104
|
+
|
105
|
+
local eventsKey = KEYS[5]
|
106
|
+
local metaKey = KEYS[2]
|
107
|
+
local maxEvents = getOrSetMaxEvents(metaKey)
|
108
|
+
|
109
|
+
rcall("INCR", KEYS[3])
|
110
|
+
|
111
|
+
local delayedOpts = cmsgpack.unpack(ARGV[6])
|
112
|
+
|
113
|
+
addDelayedJob(nextDelayedJobKey, nextDelayedJobId, delayedKey, eventsKey, schedulerOpts['name'], ARGV[4], delayedOpts,
|
114
|
+
timestamp, jobSchedulerId, maxEvents, KEYS[1], nil, nil)
|
115
|
+
|
116
|
+
if ARGV[9] ~= "" then
|
117
|
+
rcall("HSET", ARGV[9], "nrjid", nextDelayedJobId)
|
118
|
+
end
|
119
|
+
|
120
|
+
return nextDelayedJobId .. "" -- convert to string
|
@@ -0,0 +1,25 @@
|
|
1
|
+
--[[
|
2
|
+
Add marker if needed when a job is available.
|
3
|
+
]]
|
4
|
+
|
5
|
+
-- Includes
|
6
|
+
--- @include "addDelayMarkerIfNeeded"
|
7
|
+
--- @include "getDelayedScore"
|
8
|
+
--- @include "storeJob"
|
9
|
+
|
10
|
+
local function addDelayedJob(jobIdKey, jobId, delayedKey, eventsKey, name, data, opts, timestamp, repeatJobKey,
|
11
|
+
maxEvents, markerKey, parentKey, parentData)
|
12
|
+
-- Store the job.
|
13
|
+
local delay, priority = storeJob(eventsKey, jobIdKey, jobId, name, data,
|
14
|
+
opts, timestamp, parentKey, parentData, repeatJobKey)
|
15
|
+
|
16
|
+
local score, delayedTimestamp = getDelayedScore(delayedKey, timestamp, tonumber(delay))
|
17
|
+
|
18
|
+
rcall("ZADD", delayedKey, score, jobId)
|
19
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "delayed",
|
20
|
+
"jobId", jobId, "delay", delayedTimestamp)
|
21
|
+
|
22
|
+
-- mark that a delayed job is available
|
23
|
+
addDelayMarkerIfNeeded(markerKey, delayedKey)
|
24
|
+
end
|
25
|
+
|
@@ -48,6 +48,10 @@ local repeatJobKey = args[9]
|
|
48
48
|
local deduplicationKey = args[10]
|
49
49
|
local parentData
|
50
50
|
-- Includes
|
51
|
+
--[[
|
52
|
+
Add marker if needed when a job is available.
|
53
|
+
]]
|
54
|
+
-- Includes
|
51
55
|
--[[
|
52
56
|
Add delay marker if needed.
|
53
57
|
]]
|
@@ -72,29 +76,6 @@ local function addDelayMarkerIfNeeded(markerKey, delayedKey)
|
|
72
76
|
rcall("ZADD", markerKey, nextTimestamp, "1")
|
73
77
|
end
|
74
78
|
end
|
75
|
-
--[[
|
76
|
-
Function to debounce a job.
|
77
|
-
]]
|
78
|
-
local function deduplicateJob(prefixKey, deduplicationOpts, jobId, deduplicationKey, eventsKey, maxEvents)
|
79
|
-
local deduplicationId = deduplicationOpts and deduplicationOpts['id']
|
80
|
-
if deduplicationId then
|
81
|
-
local ttl = deduplicationOpts['ttl']
|
82
|
-
local deduplicationKeyExists
|
83
|
-
if ttl then
|
84
|
-
deduplicationKeyExists = not rcall('SET', deduplicationKey, jobId, 'PX', ttl, 'NX')
|
85
|
-
else
|
86
|
-
deduplicationKeyExists = not rcall('SET', deduplicationKey, jobId, 'NX')
|
87
|
-
end
|
88
|
-
if deduplicationKeyExists then
|
89
|
-
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
90
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event",
|
91
|
-
"debounced", "jobId", currentDebounceJobId, "debounceId", deduplicationId)
|
92
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event",
|
93
|
-
"deduplicated", "jobId", currentDebounceJobId, "deduplicationId", deduplicationId)
|
94
|
-
return currentDebounceJobId
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
79
|
--[[
|
99
80
|
Bake in the job id first 12 bits into the timestamp
|
100
81
|
to guarantee correct execution order of delayed jobs
|
@@ -119,6 +100,71 @@ local function getDelayedScore(delayedKey, timestamp, delay)
|
|
119
100
|
end
|
120
101
|
return minScore, delayedTimestamp
|
121
102
|
end
|
103
|
+
--[[
|
104
|
+
Function to store a job
|
105
|
+
]]
|
106
|
+
local function storeJob(eventsKey, jobIdKey, jobId, name, data, opts, timestamp,
|
107
|
+
parentKey, parentData, repeatJobKey)
|
108
|
+
local jsonOpts = cjson.encode(opts)
|
109
|
+
local delay = opts['delay'] or 0
|
110
|
+
local priority = opts['priority'] or 0
|
111
|
+
local debounceId = opts['de'] and opts['de']['id']
|
112
|
+
local optionalValues = {}
|
113
|
+
if parentKey ~= nil then
|
114
|
+
table.insert(optionalValues, "parentKey")
|
115
|
+
table.insert(optionalValues, parentKey)
|
116
|
+
table.insert(optionalValues, "parent")
|
117
|
+
table.insert(optionalValues, parentData)
|
118
|
+
end
|
119
|
+
if repeatJobKey ~= nil then
|
120
|
+
table.insert(optionalValues, "rjk")
|
121
|
+
table.insert(optionalValues, repeatJobKey)
|
122
|
+
end
|
123
|
+
if debounceId then
|
124
|
+
table.insert(optionalValues, "deid")
|
125
|
+
table.insert(optionalValues, debounceId)
|
126
|
+
end
|
127
|
+
rcall("HMSET", jobIdKey, "name", name, "data", data, "opts", jsonOpts,
|
128
|
+
"timestamp", timestamp, "delay", delay, "priority", priority,
|
129
|
+
unpack(optionalValues))
|
130
|
+
rcall("XADD", eventsKey, "*", "event", "added", "jobId", jobId, "name", name)
|
131
|
+
return delay, priority
|
132
|
+
end
|
133
|
+
local function addDelayedJob(jobIdKey, jobId, delayedKey, eventsKey, name, data, opts, timestamp, repeatJobKey,
|
134
|
+
maxEvents, markerKey, parentKey, parentData)
|
135
|
+
-- Store the job.
|
136
|
+
local delay, priority = storeJob(eventsKey, jobIdKey, jobId, name, data,
|
137
|
+
opts, timestamp, parentKey, parentData, repeatJobKey)
|
138
|
+
local score, delayedTimestamp = getDelayedScore(delayedKey, timestamp, tonumber(delay))
|
139
|
+
rcall("ZADD", delayedKey, score, jobId)
|
140
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "delayed",
|
141
|
+
"jobId", jobId, "delay", delayedTimestamp)
|
142
|
+
-- mark that a delayed job is available
|
143
|
+
addDelayMarkerIfNeeded(markerKey, delayedKey)
|
144
|
+
end
|
145
|
+
--[[
|
146
|
+
Function to debounce a job.
|
147
|
+
]]
|
148
|
+
local function deduplicateJob(prefixKey, deduplicationOpts, jobId, deduplicationKey, eventsKey, maxEvents)
|
149
|
+
local deduplicationId = deduplicationOpts and deduplicationOpts['id']
|
150
|
+
if deduplicationId then
|
151
|
+
local ttl = deduplicationOpts['ttl']
|
152
|
+
local deduplicationKeyExists
|
153
|
+
if ttl then
|
154
|
+
deduplicationKeyExists = not rcall('SET', deduplicationKey, jobId, 'PX', ttl, 'NX')
|
155
|
+
else
|
156
|
+
deduplicationKeyExists = not rcall('SET', deduplicationKey, jobId, 'NX')
|
157
|
+
end
|
158
|
+
if deduplicationKeyExists then
|
159
|
+
local currentDebounceJobId = rcall('GET', deduplicationKey)
|
160
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event",
|
161
|
+
"debounced", "jobId", currentDebounceJobId, "debounceId", deduplicationId)
|
162
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event",
|
163
|
+
"deduplicated", "jobId", currentDebounceJobId, "deduplicationId", deduplicationId)
|
164
|
+
return currentDebounceJobId
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
122
168
|
--[[
|
123
169
|
Function to get max events value or set by default 10000.
|
124
170
|
]]
|
@@ -292,36 +338,6 @@ local function handleDuplicatedJob(jobKey, jobId, currentParentKey, currentParen
|
|
292
338
|
"duplicated", "jobId", jobId)
|
293
339
|
return jobId .. "" -- convert to string
|
294
340
|
end
|
295
|
-
--[[
|
296
|
-
Function to store a job
|
297
|
-
]]
|
298
|
-
local function storeJob(eventsKey, jobIdKey, jobId, name, data, opts, timestamp,
|
299
|
-
parentKey, parentData, repeatJobKey)
|
300
|
-
local jsonOpts = cjson.encode(opts)
|
301
|
-
local delay = opts['delay'] or 0
|
302
|
-
local priority = opts['priority'] or 0
|
303
|
-
local debounceId = opts['de'] and opts['de']['id']
|
304
|
-
local optionalValues = {}
|
305
|
-
if parentKey ~= nil then
|
306
|
-
table.insert(optionalValues, "parentKey")
|
307
|
-
table.insert(optionalValues, parentKey)
|
308
|
-
table.insert(optionalValues, "parent")
|
309
|
-
table.insert(optionalValues, parentData)
|
310
|
-
end
|
311
|
-
if repeatJobKey ~= nil then
|
312
|
-
table.insert(optionalValues, "rjk")
|
313
|
-
table.insert(optionalValues, repeatJobKey)
|
314
|
-
end
|
315
|
-
if debounceId then
|
316
|
-
table.insert(optionalValues, "deid")
|
317
|
-
table.insert(optionalValues, debounceId)
|
318
|
-
end
|
319
|
-
rcall("HMSET", jobIdKey, "name", name, "data", data, "opts", jsonOpts,
|
320
|
-
"timestamp", timestamp, "delay", delay, "priority", priority,
|
321
|
-
unpack(optionalValues))
|
322
|
-
rcall("XADD", eventsKey, "*", "event", "added", "jobId", jobId, "name", name)
|
323
|
-
return delay, priority
|
324
|
-
end
|
325
341
|
if parentKey ~= nil then
|
326
342
|
if rcall("EXISTS", parentKey) ~= 1 then return -5 end
|
327
343
|
parentData = cjson.encode(parent)
|
@@ -348,17 +364,8 @@ local deduplicationJobId = deduplicateJob(args[1], opts['de'],
|
|
348
364
|
if deduplicationJobId then
|
349
365
|
return deduplicationJobId
|
350
366
|
end
|
351
|
-
|
352
|
-
|
353
|
-
opts, timestamp, parentKey, parentData,
|
354
|
-
repeatJobKey)
|
355
|
-
local score, delayedTimestamp = getDelayedScore(delayedKey, timestamp, tonumber(delay))
|
356
|
-
rcall("ZADD", delayedKey, score, jobId)
|
357
|
-
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "delayed",
|
358
|
-
"jobId", jobId, "delay", delayedTimestamp)
|
359
|
-
-- mark that a delayed job is available
|
360
|
-
local markerKey = KEYS[1]
|
361
|
-
addDelayMarkerIfNeeded(markerKey, delayedKey)
|
367
|
+
addDelayedJob(jobIdKey, jobId, delayedKey, eventsKey, args[3], ARGV[2], opts, timestamp, repeatJobKey,
|
368
|
+
maxEvents, KEYS[1], parentKey, parentData)
|
362
369
|
-- Check if this job is a child of another job, if so add it to the parents dependencies
|
363
370
|
if parentDependenciesKey ~= nil then
|
364
371
|
rcall("SADD", parentDependenciesKey, jobIdKey)
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkXf,CAAC;AACW,QAAA,aAAa,GAAG;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|
@@ -4,8 +4,12 @@ exports.addJobScheduler = void 0;
|
|
4
4
|
const content = `--[[
|
5
5
|
Adds a job scheduler, i.e. a job factory that creates jobs based on a given schedule (repeat options).
|
6
6
|
Input:
|
7
|
-
KEYS[1] '
|
8
|
-
KEYS[2] '
|
7
|
+
KEYS[1] 'marker',
|
8
|
+
KEYS[2] 'meta'
|
9
|
+
KEYS[3] 'id'
|
10
|
+
KEYS[4] 'delayed'
|
11
|
+
KEYS[5] events stream key
|
12
|
+
KEYS[6] 'repeat' key
|
9
13
|
ARGV[1] next milliseconds
|
10
14
|
ARGV[2] msgpacked options
|
11
15
|
[1] name
|
@@ -15,19 +19,128 @@ const content = `--[[
|
|
15
19
|
[5] every?
|
16
20
|
ARGV[3] jobs scheduler id
|
17
21
|
ARGV[4] Json stringified template data
|
18
|
-
ARGV[5]
|
19
|
-
ARGV[6]
|
22
|
+
ARGV[5] msgpacked template opts
|
23
|
+
ARGV[6] msgpacked delayed opts
|
24
|
+
ARGV[7] timestamp
|
25
|
+
ARGV[8] prefix key
|
26
|
+
ARGV[9] producer key
|
20
27
|
Output:
|
21
|
-
|
28
|
+
next delayed job id - OK
|
22
29
|
]]
|
23
30
|
local rcall = redis.call
|
24
|
-
local repeatKey = KEYS[
|
25
|
-
local delayedKey = KEYS[
|
31
|
+
local repeatKey = KEYS[6]
|
32
|
+
local delayedKey = KEYS[4]
|
33
|
+
local timestamp = ARGV[7]
|
26
34
|
local nextMillis = ARGV[1]
|
27
35
|
local jobSchedulerId = ARGV[3]
|
28
36
|
local templateOpts = cmsgpack.unpack(ARGV[5])
|
29
|
-
local prefixKey = ARGV[
|
37
|
+
local prefixKey = ARGV[8]
|
30
38
|
-- Includes
|
39
|
+
--[[
|
40
|
+
Add marker if needed when a job is available.
|
41
|
+
]]
|
42
|
+
-- Includes
|
43
|
+
--[[
|
44
|
+
Add delay marker if needed.
|
45
|
+
]]
|
46
|
+
-- Includes
|
47
|
+
--[[
|
48
|
+
Function to return the next delayed job timestamp.
|
49
|
+
]]
|
50
|
+
local function getNextDelayedTimestamp(delayedKey)
|
51
|
+
local result = rcall("ZRANGE", delayedKey, 0, 0, "WITHSCORES")
|
52
|
+
if #result then
|
53
|
+
local nextTimestamp = tonumber(result[2])
|
54
|
+
if nextTimestamp ~= nil then
|
55
|
+
return nextTimestamp / 0x1000
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
local function addDelayMarkerIfNeeded(markerKey, delayedKey)
|
60
|
+
local nextTimestamp = getNextDelayedTimestamp(delayedKey)
|
61
|
+
if nextTimestamp ~= nil then
|
62
|
+
-- Replace the score of the marker with the newest known
|
63
|
+
-- next timestamp.
|
64
|
+
rcall("ZADD", markerKey, nextTimestamp, "1")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
--[[
|
68
|
+
Bake in the job id first 12 bits into the timestamp
|
69
|
+
to guarantee correct execution order of delayed jobs
|
70
|
+
(up to 4096 jobs per given timestamp or 4096 jobs apart per timestamp)
|
71
|
+
WARNING: Jobs that are so far apart that they wrap around will cause FIFO to fail
|
72
|
+
]]
|
73
|
+
local function getDelayedScore(delayedKey, timestamp, delay)
|
74
|
+
local delayedTimestamp = (delay > 0 and (tonumber(timestamp) + delay)) or tonumber(timestamp)
|
75
|
+
local minScore = delayedTimestamp * 0x1000
|
76
|
+
local maxScore = (delayedTimestamp + 1 ) * 0x1000 - 1
|
77
|
+
local result = rcall("ZREVRANGEBYSCORE", delayedKey, maxScore,
|
78
|
+
minScore, "WITHSCORES","LIMIT", 0, 1)
|
79
|
+
if #result then
|
80
|
+
local currentMaxScore = tonumber(result[2])
|
81
|
+
if currentMaxScore ~= nil then
|
82
|
+
if currentMaxScore >= maxScore then
|
83
|
+
return maxScore, delayedTimestamp
|
84
|
+
else
|
85
|
+
return currentMaxScore + 1, delayedTimestamp
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return minScore, delayedTimestamp
|
90
|
+
end
|
91
|
+
--[[
|
92
|
+
Function to store a job
|
93
|
+
]]
|
94
|
+
local function storeJob(eventsKey, jobIdKey, jobId, name, data, opts, timestamp,
|
95
|
+
parentKey, parentData, repeatJobKey)
|
96
|
+
local jsonOpts = cjson.encode(opts)
|
97
|
+
local delay = opts['delay'] or 0
|
98
|
+
local priority = opts['priority'] or 0
|
99
|
+
local debounceId = opts['de'] and opts['de']['id']
|
100
|
+
local optionalValues = {}
|
101
|
+
if parentKey ~= nil then
|
102
|
+
table.insert(optionalValues, "parentKey")
|
103
|
+
table.insert(optionalValues, parentKey)
|
104
|
+
table.insert(optionalValues, "parent")
|
105
|
+
table.insert(optionalValues, parentData)
|
106
|
+
end
|
107
|
+
if repeatJobKey ~= nil then
|
108
|
+
table.insert(optionalValues, "rjk")
|
109
|
+
table.insert(optionalValues, repeatJobKey)
|
110
|
+
end
|
111
|
+
if debounceId then
|
112
|
+
table.insert(optionalValues, "deid")
|
113
|
+
table.insert(optionalValues, debounceId)
|
114
|
+
end
|
115
|
+
rcall("HMSET", jobIdKey, "name", name, "data", data, "opts", jsonOpts,
|
116
|
+
"timestamp", timestamp, "delay", delay, "priority", priority,
|
117
|
+
unpack(optionalValues))
|
118
|
+
rcall("XADD", eventsKey, "*", "event", "added", "jobId", jobId, "name", name)
|
119
|
+
return delay, priority
|
120
|
+
end
|
121
|
+
local function addDelayedJob(jobIdKey, jobId, delayedKey, eventsKey, name, data, opts, timestamp, repeatJobKey,
|
122
|
+
maxEvents, markerKey, parentKey, parentData)
|
123
|
+
-- Store the job.
|
124
|
+
local delay, priority = storeJob(eventsKey, jobIdKey, jobId, name, data,
|
125
|
+
opts, timestamp, parentKey, parentData, repeatJobKey)
|
126
|
+
local score, delayedTimestamp = getDelayedScore(delayedKey, timestamp, tonumber(delay))
|
127
|
+
rcall("ZADD", delayedKey, score, jobId)
|
128
|
+
rcall("XADD", eventsKey, "MAXLEN", "~", maxEvents, "*", "event", "delayed",
|
129
|
+
"jobId", jobId, "delay", delayedTimestamp)
|
130
|
+
-- mark that a delayed job is available
|
131
|
+
addDelayMarkerIfNeeded(markerKey, delayedKey)
|
132
|
+
end
|
133
|
+
--[[
|
134
|
+
Function to get max events value or set by default 10000.
|
135
|
+
]]
|
136
|
+
local function getOrSetMaxEvents(metaKey)
|
137
|
+
local maxEvents = rcall("HGET", metaKey, "opts.maxLenEvents")
|
138
|
+
if not maxEvents then
|
139
|
+
maxEvents = 10000
|
140
|
+
rcall("HSET", metaKey, "opts.maxLenEvents", maxEvents)
|
141
|
+
end
|
142
|
+
return maxEvents
|
143
|
+
end
|
31
144
|
--[[
|
32
145
|
Function to remove job.
|
33
146
|
]]
|
@@ -181,9 +294,8 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
|
181
294
|
end
|
182
295
|
removeJobKeys(jobKey)
|
183
296
|
end
|
184
|
-
local function storeRepeatableJob(schedulerId, repeatKey, nextMillis,
|
297
|
+
local function storeRepeatableJob(schedulerId, schedulerKey, repeatKey, nextMillis, opts, templateData, templateOpts)
|
185
298
|
rcall("ZADD", repeatKey, nextMillis, schedulerId)
|
186
|
-
local opts = cmsgpack.unpack(rawOpts)
|
187
299
|
local optionalValues = {}
|
188
300
|
if opts['tz'] then
|
189
301
|
table.insert(optionalValues, "tz")
|
@@ -210,16 +322,17 @@ local function storeRepeatableJob(schedulerId, repeatKey, nextMillis, rawOpts, t
|
|
210
322
|
table.insert(optionalValues, "data")
|
211
323
|
table.insert(optionalValues, templateData)
|
212
324
|
end
|
213
|
-
rcall("HMSET",
|
325
|
+
rcall("HMSET", schedulerKey, "name", opts['name'],
|
214
326
|
unpack(optionalValues))
|
215
327
|
end
|
328
|
+
local schedulerKey = repeatKey .. ":" .. jobSchedulerId
|
329
|
+
local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
|
330
|
+
local nextDelayedJobKey = schedulerKey .. ":" .. nextMillis
|
216
331
|
-- If we are overriding a repeatable job we must delete the delayed job for
|
217
332
|
-- the next iteration.
|
218
333
|
local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
|
219
334
|
if prevMillis ~= false then
|
220
335
|
local delayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
|
221
|
-
local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
|
222
|
-
local nextDelayedJobKey = repeatKey .. ":" .. jobSchedulerId .. ":" .. nextMillis
|
223
336
|
if rcall("ZSCORE", delayedKey, delayedJobId) ~= false
|
224
337
|
and (rcall("EXISTS", nextDelayedJobKey) ~= 1
|
225
338
|
or delayedJobId == nextDelayedJobId) then
|
@@ -227,11 +340,23 @@ if prevMillis ~= false then
|
|
227
340
|
rcall("ZREM", delayedKey, delayedJobId)
|
228
341
|
end
|
229
342
|
end
|
230
|
-
|
343
|
+
local schedulerOpts = cmsgpack.unpack(ARGV[2])
|
344
|
+
storeRepeatableJob(jobSchedulerId, schedulerKey, repeatKey, nextMillis, schedulerOpts, ARGV[4], templateOpts)
|
345
|
+
local eventsKey = KEYS[5]
|
346
|
+
local metaKey = KEYS[2]
|
347
|
+
local maxEvents = getOrSetMaxEvents(metaKey)
|
348
|
+
rcall("INCR", KEYS[3])
|
349
|
+
local delayedOpts = cmsgpack.unpack(ARGV[6])
|
350
|
+
addDelayedJob(nextDelayedJobKey, nextDelayedJobId, delayedKey, eventsKey, schedulerOpts['name'], ARGV[4], delayedOpts,
|
351
|
+
timestamp, jobSchedulerId, maxEvents, KEYS[1], nil, nil)
|
352
|
+
if ARGV[9] ~= "" then
|
353
|
+
rcall("HSET", ARGV[9], "nrjid", nextDelayedJobId)
|
354
|
+
end
|
355
|
+
return nextDelayedJobId .. "" -- convert to string
|
231
356
|
`;
|
232
357
|
exports.addJobScheduler = {
|
233
358
|
name: 'addJobScheduler',
|
234
359
|
content,
|
235
|
-
keys:
|
360
|
+
keys: 6,
|
236
361
|
};
|
237
|
-
//# sourceMappingURL=addJobScheduler-
|
362
|
+
//# sourceMappingURL=addJobScheduler-6.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"addJobScheduler-6.js","sourceRoot":"","sources":["../../../src/scripts/addJobScheduler-6.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgWf,CAAC;AACW,QAAA,eAAe,GAAG;IAC7B,IAAI,EAAE,iBAAiB;IACvB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const tslib_1 = require("tslib");
|
4
4
|
tslib_1.__exportStar(require("./addDelayedJob-6"), exports);
|
5
|
-
tslib_1.__exportStar(require("./addJobScheduler-
|
5
|
+
tslib_1.__exportStar(require("./addJobScheduler-6"), exports);
|
6
6
|
tslib_1.__exportStar(require("./addLog-2"), exports);
|
7
7
|
tslib_1.__exportStar(require("./addParentJob-4"), exports);
|
8
8
|
tslib_1.__exportStar(require("./addPrioritizedJob-8"), exports);
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.removeJobScheduler = void 0;
|
4
4
|
const content = `--[[
|
5
|
-
Removes a
|
5
|
+
Removes a job scheduler and its next scheduled job.
|
6
6
|
Input:
|
7
7
|
KEYS[1] job schedulers key
|
8
8
|
KEYS[2] delayed jobs key
|