bullmq 5.39.2 → 5.40.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.
Files changed (38) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/classes/job-scheduler.js +44 -63
  3. package/dist/cjs/classes/job-scheduler.js.map +1 -1
  4. package/dist/cjs/classes/scripts.js +5 -37
  5. package/dist/cjs/classes/scripts.js.map +1 -1
  6. package/dist/cjs/classes/worker.js +68 -74
  7. package/dist/cjs/classes/worker.js.map +1 -1
  8. package/dist/cjs/commands/addJobScheduler-2.lua +88 -0
  9. package/dist/cjs/scripts/addJobScheduler-2.js +234 -0
  10. package/dist/cjs/scripts/addJobScheduler-2.js.map +1 -0
  11. package/dist/cjs/scripts/index.js +1 -1
  12. package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
  13. package/dist/cjs/version.js +1 -1
  14. package/dist/esm/classes/job-scheduler.d.ts +1 -1
  15. package/dist/esm/classes/job-scheduler.js +44 -63
  16. package/dist/esm/classes/job-scheduler.js.map +1 -1
  17. package/dist/esm/classes/scripts.d.ts +3 -3
  18. package/dist/esm/classes/scripts.js +5 -37
  19. package/dist/esm/classes/scripts.js.map +1 -1
  20. package/dist/esm/classes/worker.d.ts +8 -2
  21. package/dist/esm/classes/worker.js +68 -74
  22. package/dist/esm/classes/worker.js.map +1 -1
  23. package/dist/esm/commands/addJobScheduler-2.lua +88 -0
  24. package/dist/esm/scripts/addJobScheduler-2.js +231 -0
  25. package/dist/esm/scripts/addJobScheduler-2.js.map +1 -0
  26. package/dist/esm/scripts/index.d.ts +1 -1
  27. package/dist/esm/scripts/index.js +1 -1
  28. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  29. package/dist/esm/version.d.ts +1 -1
  30. package/dist/esm/version.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/cjs/commands/addJobScheduler-6.lua +0 -125
  33. package/dist/cjs/scripts/addJobScheduler-6.js +0 -369
  34. package/dist/cjs/scripts/addJobScheduler-6.js.map +0 -1
  35. package/dist/esm/commands/addJobScheduler-6.lua +0 -125
  36. package/dist/esm/scripts/addJobScheduler-6.js +0 -366
  37. package/dist/esm/scripts/addJobScheduler-6.js.map +0 -1
  38. /package/dist/esm/scripts/{addJobScheduler-6.d.ts → addJobScheduler-2.d.ts} +0 -0
@@ -1,366 +0,0 @@
1
- const content = `--[[
2
- Adds a job scheduler, i.e. a job factory that creates jobs based on a given schedule (repeat options).
3
- Input:
4
- KEYS[1] 'marker',
5
- KEYS[2] 'meta'
6
- KEYS[3] 'id'
7
- KEYS[4] 'delayed'
8
- KEYS[5] events stream key
9
- KEYS[6] 'repeat' key
10
- ARGV[1] next milliseconds
11
- ARGV[2] msgpacked options
12
- [1] name
13
- [2] tz?
14
- [3] patten?
15
- [4] endDate?
16
- [5] every?
17
- ARGV[3] jobs scheduler id
18
- ARGV[4] Json stringified template data
19
- ARGV[5] msgpacked template opts
20
- ARGV[6] msgpacked delayed opts
21
- ARGV[7] timestamp
22
- ARGV[8] prefix key
23
- ARGV[9] producer key
24
- Output:
25
- next delayed job id - OK
26
- ]]
27
- local rcall = redis.call
28
- local repeatKey = KEYS[6]
29
- local delayedKey = KEYS[4]
30
- local timestamp = ARGV[7]
31
- local nextMillis = ARGV[1]
32
- local jobSchedulerId = ARGV[3]
33
- local templateOpts = cmsgpack.unpack(ARGV[5])
34
- local prefixKey = ARGV[8]
35
- -- Includes
36
- --[[
37
- Adds a delayed job to the queue by doing the following:
38
- - Creates a new job key with the job data.
39
- - adds to delayed zset.
40
- - Emits a global event 'delayed' if the job is delayed.
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
144
- --[[
145
- Function to remove job.
146
- ]]
147
- -- Includes
148
- --[[
149
- Function to remove deduplication key.
150
- ]]
151
- local function removeDeduplicationKey(prefixKey, jobKey)
152
- local deduplicationId = rcall("HGET", jobKey, "deid")
153
- if deduplicationId then
154
- local deduplicationKey = prefixKey .. "de:" .. deduplicationId
155
- rcall("DEL", deduplicationKey)
156
- end
157
- end
158
- --[[
159
- Function to remove job keys.
160
- ]]
161
- local function removeJobKeys(jobKey)
162
- return rcall("DEL", jobKey, jobKey .. ':logs',
163
- jobKey .. ':dependencies', jobKey .. ':processed', jobKey .. ':failed')
164
- end
165
- --[[
166
- Check if this job has a parent. If so we will just remove it from
167
- the parent child list, but if it is the last child we should move the parent to "wait/paused"
168
- which requires code from "moveToFinished"
169
- ]]
170
- -- Includes
171
- --[[
172
- Function to add job in target list and add marker if needed.
173
- ]]
174
- -- Includes
175
- --[[
176
- Add marker if needed when a job is available.
177
- ]]
178
- local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
179
- if not isPausedOrMaxed then
180
- rcall("ZADD", markerKey, 0, "0")
181
- end
182
- end
183
- local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
184
- rcall(pushCmd, targetKey, jobId)
185
- addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
186
- end
187
- --[[
188
- Functions to destructure job key.
189
- Just a bit of warning, these functions may be a bit slow and affect performance significantly.
190
- ]]
191
- local getJobIdFromKey = function (jobKey)
192
- return string.match(jobKey, ".*:(.*)")
193
- end
194
- local getJobKeyPrefix = function (jobKey, jobId)
195
- return string.sub(jobKey, 0, #jobKey - #jobId)
196
- end
197
- --[[
198
- Function to check for the meta.paused key to decide if we are paused or not
199
- (since an empty list and !EXISTS are not really the same).
200
- ]]
201
- local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
202
- local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
203
- if queueAttributes[1] then
204
- return pausedKey, true
205
- else
206
- if queueAttributes[2] then
207
- local activeCount = rcall("LLEN", activeKey)
208
- if activeCount >= tonumber(queueAttributes[2]) then
209
- return waitKey, true
210
- else
211
- return waitKey, false
212
- end
213
- end
214
- end
215
- return waitKey, false
216
- end
217
- local function moveParentToWait(parentPrefix, parentId, emitEvent)
218
- local parentTarget, isPausedOrMaxed = getTargetQueueList(parentPrefix .. "meta", parentPrefix .. "active",
219
- parentPrefix .. "wait", parentPrefix .. "paused")
220
- addJobInTargetList(parentTarget, parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
221
- if emitEvent then
222
- local parentEventStream = parentPrefix .. "events"
223
- rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
224
- end
225
- end
226
- local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
227
- if parentKey then
228
- local parentDependenciesKey = parentKey .. ":dependencies"
229
- local result = rcall("SREM", parentDependenciesKey, jobKey)
230
- if result > 0 then
231
- local pendingDependencies = rcall("SCARD", parentDependenciesKey)
232
- if pendingDependencies == 0 then
233
- local parentId = getJobIdFromKey(parentKey)
234
- local parentPrefix = getJobKeyPrefix(parentKey, parentId)
235
- local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
236
- if numRemovedElements == 1 then
237
- if hard then -- remove parent in same queue
238
- if parentPrefix == baseKey then
239
- removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
240
- removeJobKeys(parentKey)
241
- if debounceId then
242
- rcall("DEL", parentPrefix .. "de:" .. debounceId)
243
- end
244
- else
245
- moveParentToWait(parentPrefix, parentId)
246
- end
247
- else
248
- moveParentToWait(parentPrefix, parentId, true)
249
- end
250
- end
251
- end
252
- return true
253
- end
254
- else
255
- local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
256
- local missedParentKey = parentAttributes[1]
257
- if( (type(missedParentKey) == "string") and missedParentKey ~= ""
258
- and (rcall("EXISTS", missedParentKey) == 1)) then
259
- local parentDependenciesKey = missedParentKey .. ":dependencies"
260
- local result = rcall("SREM", parentDependenciesKey, jobKey)
261
- if result > 0 then
262
- local pendingDependencies = rcall("SCARD", parentDependenciesKey)
263
- if pendingDependencies == 0 then
264
- local parentId = getJobIdFromKey(missedParentKey)
265
- local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
266
- local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
267
- if numRemovedElements == 1 then
268
- if hard then
269
- if parentPrefix == baseKey then
270
- removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
271
- removeJobKeys(missedParentKey)
272
- if parentAttributes[2] then
273
- rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
274
- end
275
- else
276
- moveParentToWait(parentPrefix, parentId)
277
- end
278
- else
279
- moveParentToWait(parentPrefix, parentId, true)
280
- end
281
- end
282
- end
283
- return true
284
- end
285
- end
286
- end
287
- return false
288
- end
289
- local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
290
- local jobKey = baseKey .. jobId
291
- removeParentDependencyKey(jobKey, hard, nil, baseKey)
292
- if shouldRemoveDeduplicationKey then
293
- removeDeduplicationKey(baseKey, jobKey)
294
- end
295
- removeJobKeys(jobKey)
296
- end
297
- local function storeRepeatableJob(schedulerId, schedulerKey, repeatKey, nextMillis, opts, templateData, templateOpts)
298
- rcall("ZADD", repeatKey, nextMillis, schedulerId)
299
- local optionalValues = {}
300
- if opts['tz'] then
301
- table.insert(optionalValues, "tz")
302
- table.insert(optionalValues, opts['tz'])
303
- end
304
- if opts['limit'] then
305
- table.insert(optionalValues, "limit")
306
- table.insert(optionalValues, opts['limit'])
307
- end
308
- if opts['pattern'] then
309
- table.insert(optionalValues, "pattern")
310
- table.insert(optionalValues, opts['pattern'])
311
- end
312
- if opts['endDate'] then
313
- table.insert(optionalValues, "endDate")
314
- table.insert(optionalValues, opts['endDate'])
315
- end
316
- if opts['every'] then
317
- table.insert(optionalValues, "every")
318
- table.insert(optionalValues, opts['every'])
319
- end
320
- local jsonTemplateOpts = cjson.encode(templateOpts)
321
- if jsonTemplateOpts and jsonTemplateOpts ~= '{}' then
322
- table.insert(optionalValues, "opts")
323
- table.insert(optionalValues, jsonTemplateOpts)
324
- end
325
- if templateData and templateData ~= '{}' then
326
- table.insert(optionalValues, "data")
327
- table.insert(optionalValues, templateData)
328
- end
329
- rcall("HMSET", schedulerKey, "name", opts['name'], "ic", 1,
330
- unpack(optionalValues))
331
- end
332
- local schedulerKey = repeatKey .. ":" .. jobSchedulerId
333
- local nextDelayedJobId = "repeat:" .. jobSchedulerId .. ":" .. nextMillis
334
- local nextDelayedJobKey = schedulerKey .. ":" .. nextMillis
335
- -- If we are overriding a repeatable job we must delete the delayed job for
336
- -- the next iteration.
337
- local prevMillis = rcall("ZSCORE", repeatKey, jobSchedulerId)
338
- if prevMillis ~= false then
339
- local delayedJobId = "repeat:" .. jobSchedulerId .. ":" .. prevMillis
340
- if rcall("ZSCORE", delayedKey, delayedJobId) ~= false
341
- and (rcall("EXISTS", nextDelayedJobKey) ~= 1
342
- or delayedJobId == nextDelayedJobId) then
343
- removeJob(delayedJobId, true, prefixKey, true --[[remove debounce key]])
344
- rcall("ZREM", delayedKey, delayedJobId)
345
- end
346
- end
347
- local schedulerOpts = cmsgpack.unpack(ARGV[2])
348
- storeRepeatableJob(jobSchedulerId, schedulerKey, repeatKey, nextMillis, schedulerOpts, ARGV[4], templateOpts)
349
- local eventsKey = KEYS[5]
350
- local metaKey = KEYS[2]
351
- local maxEvents = getOrSetMaxEvents(metaKey)
352
- rcall("INCR", KEYS[3])
353
- local delayedOpts = cmsgpack.unpack(ARGV[6])
354
- addDelayedJob(nextDelayedJobKey, nextDelayedJobId, delayedKey, eventsKey, schedulerOpts['name'], ARGV[4], delayedOpts,
355
- timestamp, jobSchedulerId, maxEvents, KEYS[1], nil, nil)
356
- if ARGV[9] ~= "" then
357
- rcall("HSET", ARGV[9], "nrjid", nextDelayedJobId)
358
- end
359
- return nextDelayedJobId .. "" -- convert to string
360
- `;
361
- export const addJobScheduler = {
362
- name: 'addJobScheduler',
363
- content,
364
- keys: 6,
365
- };
366
- //# sourceMappingURL=addJobScheduler-6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"addJobScheduler-6.js","sourceRoot":"","sources":["../../../src/scripts/addJobScheduler-6.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuWf,CAAC;AACF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,iBAAiB;IACvB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}