bullmq 5.39.1 → 5.40.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 (36) hide show
  1. package/dist/cjs/classes/job-scheduler.js +44 -63
  2. package/dist/cjs/classes/job-scheduler.js.map +1 -1
  3. package/dist/cjs/classes/scripts.js +5 -37
  4. package/dist/cjs/classes/scripts.js.map +1 -1
  5. package/dist/cjs/classes/worker.js +1 -1
  6. package/dist/cjs/classes/worker.js.map +1 -1
  7. package/dist/cjs/commands/addJobScheduler-2.lua +88 -0
  8. package/dist/cjs/scripts/addJobScheduler-2.js +234 -0
  9. package/dist/cjs/scripts/addJobScheduler-2.js.map +1 -0
  10. package/dist/cjs/scripts/index.js +1 -1
  11. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  12. package/dist/cjs/version.js +1 -1
  13. package/dist/esm/classes/job-scheduler.d.ts +1 -1
  14. package/dist/esm/classes/job-scheduler.js +44 -63
  15. package/dist/esm/classes/job-scheduler.js.map +1 -1
  16. package/dist/esm/classes/scripts.d.ts +3 -3
  17. package/dist/esm/classes/scripts.js +5 -37
  18. package/dist/esm/classes/scripts.js.map +1 -1
  19. package/dist/esm/classes/worker.js +1 -1
  20. package/dist/esm/classes/worker.js.map +1 -1
  21. package/dist/esm/commands/addJobScheduler-2.lua +88 -0
  22. package/dist/esm/scripts/addJobScheduler-2.js +231 -0
  23. package/dist/esm/scripts/addJobScheduler-2.js.map +1 -0
  24. package/dist/esm/scripts/index.d.ts +1 -1
  25. package/dist/esm/scripts/index.js +1 -1
  26. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  27. package/dist/esm/version.d.ts +1 -1
  28. package/dist/esm/version.js +1 -1
  29. package/package.json +1 -1
  30. package/dist/cjs/commands/addJobScheduler-6.lua +0 -125
  31. package/dist/cjs/scripts/addJobScheduler-6.js +0 -369
  32. package/dist/cjs/scripts/addJobScheduler-6.js.map +0 -1
  33. package/dist/esm/commands/addJobScheduler-6.lua +0 -125
  34. package/dist/esm/scripts/addJobScheduler-6.js +0 -366
  35. package/dist/esm/scripts/addJobScheduler-6.js.map +0 -1
  36. /package/dist/esm/scripts/{addJobScheduler-6.d.ts → addJobScheduler-2.d.ts} +0 -0
@@ -0,0 +1,88 @@
1
+ --[[
2
+ Adds a job scheduler, i.e. a job factory that creates jobs based on a given schedule (repeat options).
3
+
4
+ Input:
5
+ KEYS[1] 'repeat' key
6
+ KEYS[2] 'delayed' key
7
+
8
+ ARGV[1] next milliseconds
9
+ ARGV[2] msgpacked options
10
+ [1] name
11
+ [2] tz?
12
+ [3] patten?
13
+ [4] endDate?
14
+ [5] every?
15
+ ARGV[3] jobs scheduler id
16
+ ARGV[4] Json stringified template data
17
+ ARGV[5] mspacked template opts
18
+ ARGV[6] prefix key
19
+
20
+ Output:
21
+ repeatableKey - OK
22
+ ]] local rcall = redis.call
23
+ local repeatKey = KEYS[1]
24
+ local delayedKey = KEYS[2]
25
+
26
+ local nextMillis = ARGV[1]
27
+ local jobSchedulerId = ARGV[3]
28
+ local templateOpts = cmsgpack.unpack(ARGV[5])
29
+ local prefixKey = ARGV[6]
30
+
31
+ -- Includes
32
+ --- @include "includes/removeJob"
33
+
34
+ local function storeRepeatableJob(schedulerId, repeatKey, nextMillis, rawOpts, templateData, templateOpts)
35
+ rcall("ZADD", repeatKey, nextMillis, schedulerId)
36
+ local opts = cmsgpack.unpack(rawOpts)
37
+
38
+ local optionalValues = {}
39
+ if opts['tz'] then
40
+ table.insert(optionalValues, "tz")
41
+ table.insert(optionalValues, opts['tz'])
42
+ end
43
+
44
+ if opts['pattern'] then
45
+ table.insert(optionalValues, "pattern")
46
+ table.insert(optionalValues, opts['pattern'])
47
+ end
48
+
49
+ if opts['endDate'] then
50
+ table.insert(optionalValues, "endDate")
51
+ table.insert(optionalValues, opts['endDate'])
52
+ end
53
+
54
+ if opts['every'] then
55
+ table.insert(optionalValues, "every")
56
+ table.insert(optionalValues, opts['every'])
57
+ end
58
+
59
+ local jsonTemplateOpts = cjson.encode(templateOpts)
60
+ if jsonTemplateOpts and jsonTemplateOpts ~= '{}' then
61
+ table.insert(optionalValues, "opts")
62
+ table.insert(optionalValues, jsonTemplateOpts)
63
+ end
64
+
65
+ if templateData and templateData ~= '{}' then
66
+ table.insert(optionalValues, "data")
67
+ table.insert(optionalValues, templateData)
68
+ end
69
+
70
+ rcall("HMSET", repeatKey .. ":" .. schedulerId, "name", opts['name'], unpack(optionalValues))
71
+ end
72
+
73
+ -- If we are overriding a repeatable job we must delete the delayed job for
74
+ -- the next iteration.
75
+ local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
76
+ if prevMillis ~= false then
77
+ local delayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
78
+ local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
79
+ local nextDelayedJobKey = repeatKey .. ":" .. jobSchedulerId .. ":" .. nextMillis
80
+
81
+ if rcall("ZSCORE", delayedKey, delayedJobId) ~= false and
82
+ (rcall("EXISTS", nextDelayedJobKey) ~= 1 or delayedJobId == nextDelayedJobId) then
83
+ removeJob(delayedJobId, true, prefixKey, true --[[remove debounce key]] )
84
+ rcall("ZREM", delayedKey, delayedJobId)
85
+ end
86
+ end
87
+
88
+ return storeRepeatableJob(jobSchedulerId, repeatKey, nextMillis, ARGV[2], ARGV[4], templateOpts)
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addJobScheduler = void 0;
4
+ const content = `--[[
5
+ Adds a job scheduler, i.e. a job factory that creates jobs based on a given schedule (repeat options).
6
+ Input:
7
+ KEYS[1] 'repeat' key
8
+ KEYS[2] 'delayed' key
9
+ ARGV[1] next milliseconds
10
+ ARGV[2] msgpacked options
11
+ [1] name
12
+ [2] tz?
13
+ [3] patten?
14
+ [4] endDate?
15
+ [5] every?
16
+ ARGV[3] jobs scheduler id
17
+ ARGV[4] Json stringified template data
18
+ ARGV[5] mspacked template opts
19
+ ARGV[6] prefix key
20
+ Output:
21
+ repeatableKey - OK
22
+ ]] local rcall = redis.call
23
+ local repeatKey = KEYS[1]
24
+ local delayedKey = KEYS[2]
25
+ local nextMillis = ARGV[1]
26
+ local jobSchedulerId = ARGV[3]
27
+ local templateOpts = cmsgpack.unpack(ARGV[5])
28
+ local prefixKey = ARGV[6]
29
+ -- Includes
30
+ --[[
31
+ Function to remove job.
32
+ ]]
33
+ -- Includes
34
+ --[[
35
+ Function to remove deduplication key.
36
+ ]]
37
+ local function removeDeduplicationKey(prefixKey, jobKey)
38
+ local deduplicationId = rcall("HGET", jobKey, "deid")
39
+ if deduplicationId then
40
+ local deduplicationKey = prefixKey .. "de:" .. deduplicationId
41
+ rcall("DEL", deduplicationKey)
42
+ end
43
+ end
44
+ --[[
45
+ Function to remove job keys.
46
+ ]]
47
+ local function removeJobKeys(jobKey)
48
+ return rcall("DEL", jobKey, jobKey .. ':logs',
49
+ jobKey .. ':dependencies', jobKey .. ':processed', jobKey .. ':failed')
50
+ end
51
+ --[[
52
+ Check if this job has a parent. If so we will just remove it from
53
+ the parent child list, but if it is the last child we should move the parent to "wait/paused"
54
+ which requires code from "moveToFinished"
55
+ ]]
56
+ -- Includes
57
+ --[[
58
+ Function to add job in target list and add marker if needed.
59
+ ]]
60
+ -- Includes
61
+ --[[
62
+ Add marker if needed when a job is available.
63
+ ]]
64
+ local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
65
+ if not isPausedOrMaxed then
66
+ rcall("ZADD", markerKey, 0, "0")
67
+ end
68
+ end
69
+ local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
70
+ rcall(pushCmd, targetKey, jobId)
71
+ addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
72
+ end
73
+ --[[
74
+ Functions to destructure job key.
75
+ Just a bit of warning, these functions may be a bit slow and affect performance significantly.
76
+ ]]
77
+ local getJobIdFromKey = function (jobKey)
78
+ return string.match(jobKey, ".*:(.*)")
79
+ end
80
+ local getJobKeyPrefix = function (jobKey, jobId)
81
+ return string.sub(jobKey, 0, #jobKey - #jobId)
82
+ end
83
+ --[[
84
+ Function to check for the meta.paused key to decide if we are paused or not
85
+ (since an empty list and !EXISTS are not really the same).
86
+ ]]
87
+ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
88
+ local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
89
+ if queueAttributes[1] then
90
+ return pausedKey, true
91
+ else
92
+ if queueAttributes[2] then
93
+ local activeCount = rcall("LLEN", activeKey)
94
+ if activeCount >= tonumber(queueAttributes[2]) then
95
+ return waitKey, true
96
+ else
97
+ return waitKey, false
98
+ end
99
+ end
100
+ end
101
+ return waitKey, false
102
+ end
103
+ local function moveParentToWait(parentPrefix, parentId, emitEvent)
104
+ local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
105
+ parentPrefix .. "wait", parentPrefix .. "paused")
106
+ addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
107
+ if emitEvent then
108
+ local parentEventStream = parentPrefix .. "events"
109
+ rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
110
+ end
111
+ end
112
+ local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
113
+ if parentKey then
114
+ local parentDependenciesKey = parentKey .. ":dependencies"
115
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
116
+ if result > 0 then
117
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
118
+ if pendingDependencies == 0 then
119
+ local parentId = getJobIdFromKey(parentKey)
120
+ local parentPrefix = getJobKeyPrefix(parentKey, parentId)
121
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
122
+ if numRemovedElements == 1 then
123
+ if hard then -- remove parent in same queue
124
+ if parentPrefix == baseKey then
125
+ removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
126
+ removeJobKeys(parentKey)
127
+ if debounceId then
128
+ rcall("DEL", parentPrefix .. "de:" .. debounceId)
129
+ end
130
+ else
131
+ moveParentToWait(parentPrefix, parentId)
132
+ end
133
+ else
134
+ moveParentToWait(parentPrefix, parentId, true)
135
+ end
136
+ end
137
+ end
138
+ return true
139
+ end
140
+ else
141
+ local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
142
+ local missedParentKey = parentAttributes[1]
143
+ if( (type(missedParentKey) == "string") and missedParentKey ~= ""
144
+ and (rcall("EXISTS", missedParentKey) == 1)) then
145
+ local parentDependenciesKey = missedParentKey .. ":dependencies"
146
+ local result = rcall("SREM", parentDependenciesKey, jobKey)
147
+ if result > 0 then
148
+ local pendingDependencies = rcall("SCARD", parentDependenciesKey)
149
+ if pendingDependencies == 0 then
150
+ local parentId = getJobIdFromKey(missedParentKey)
151
+ local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
152
+ local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
153
+ if numRemovedElements == 1 then
154
+ if hard then
155
+ if parentPrefix == baseKey then
156
+ removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
157
+ removeJobKeys(missedParentKey)
158
+ if parentAttributes[2] then
159
+ rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
160
+ end
161
+ else
162
+ moveParentToWait(parentPrefix, parentId)
163
+ end
164
+ else
165
+ moveParentToWait(parentPrefix, parentId, true)
166
+ end
167
+ end
168
+ end
169
+ return true
170
+ end
171
+ end
172
+ end
173
+ return false
174
+ end
175
+ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
176
+ local jobKey = baseKey .. jobId
177
+ removeParentDependencyKey(jobKey, hard, nil, baseKey)
178
+ if shouldRemoveDeduplicationKey then
179
+ removeDeduplicationKey(baseKey, jobKey)
180
+ end
181
+ removeJobKeys(jobKey)
182
+ end
183
+ local function storeRepeatableJob(schedulerId, repeatKey, nextMillis, rawOpts, templateData, templateOpts)
184
+ rcall("ZADD", repeatKey, nextMillis, schedulerId)
185
+ local opts = cmsgpack.unpack(rawOpts)
186
+ local optionalValues = {}
187
+ if opts['tz'] then
188
+ table.insert(optionalValues, "tz")
189
+ table.insert(optionalValues, opts['tz'])
190
+ end
191
+ if opts['pattern'] then
192
+ table.insert(optionalValues, "pattern")
193
+ table.insert(optionalValues, opts['pattern'])
194
+ end
195
+ if opts['endDate'] then
196
+ table.insert(optionalValues, "endDate")
197
+ table.insert(optionalValues, opts['endDate'])
198
+ end
199
+ if opts['every'] then
200
+ table.insert(optionalValues, "every")
201
+ table.insert(optionalValues, opts['every'])
202
+ end
203
+ local jsonTemplateOpts = cjson.encode(templateOpts)
204
+ if jsonTemplateOpts and jsonTemplateOpts ~= '{}' then
205
+ table.insert(optionalValues, "opts")
206
+ table.insert(optionalValues, jsonTemplateOpts)
207
+ end
208
+ if templateData and templateData ~= '{}' then
209
+ table.insert(optionalValues, "data")
210
+ table.insert(optionalValues, templateData)
211
+ end
212
+ rcall("HMSET", repeatKey .. ":" .. schedulerId, "name", opts['name'], unpack(optionalValues))
213
+ end
214
+ -- If we are overriding a repeatable job we must delete the delayed job for
215
+ -- the next iteration.
216
+ local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
217
+ if prevMillis ~= false then
218
+ local delayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
219
+ local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
220
+ local nextDelayedJobKey = repeatKey .. ":" .. jobSchedulerId .. ":" .. nextMillis
221
+ if rcall("ZSCORE", delayedKey, delayedJobId) ~= false and
222
+ (rcall("EXISTS", nextDelayedJobKey) ~= 1 or delayedJobId == nextDelayedJobId) then
223
+ removeJob(delayedJobId, true, prefixKey, true --[[remove debounce key]] )
224
+ rcall("ZREM", delayedKey, delayedJobId)
225
+ end
226
+ end
227
+ return storeRepeatableJob(jobSchedulerId, repeatKey, nextMillis, ARGV[2], ARGV[4], templateOpts)
228
+ `;
229
+ exports.addJobScheduler = {
230
+ name: 'addJobScheduler',
231
+ content,
232
+ keys: 2,
233
+ };
234
+ //# sourceMappingURL=addJobScheduler-2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addJobScheduler-2.js","sourceRoot":"","sources":["../../../src/scripts/addJobScheduler-2.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgOf,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-6"), exports);
5
+ tslib_1.__exportStar(require("./addJobScheduler-2"), 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);