bullmq 5.29.1 → 5.30.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/cjs/classes/job-scheduler.js +4 -2
- package/dist/cjs/classes/job-scheduler.js.map +1 -1
- package/dist/cjs/classes/queue.js +9 -0
- package/dist/cjs/classes/queue.js.map +1 -1
- package/dist/cjs/commands/addJobScheduler-2.lua +4 -2
- package/dist/cjs/commands/includes/moveParentFromWaitingChildrenToFailed.lua +10 -2
- package/dist/cjs/commands/includes/removeJobsOnFail.lua +36 -0
- package/dist/cjs/commands/moveStalledJobsToWait-9.lua +2 -27
- package/dist/cjs/scripts/addJobScheduler-2.js +4 -2
- package/dist/cjs/scripts/addJobScheduler-2.js.map +1 -1
- package/dist/cjs/scripts/moveStalledJobsToWait-9.js +68 -56
- package/dist/cjs/scripts/moveStalledJobsToWait-9.js.map +1 -1
- package/dist/cjs/scripts/moveToFinished-14.js +143 -110
- package/dist/cjs/scripts/moveToFinished-14.js.map +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 +2 -2
- package/dist/esm/classes/job-scheduler.js +4 -2
- package/dist/esm/classes/job-scheduler.js.map +1 -1
- package/dist/esm/classes/queue.d.ts +7 -0
- package/dist/esm/classes/queue.js +9 -0
- package/dist/esm/classes/queue.js.map +1 -1
- package/dist/esm/commands/addJobScheduler-2.lua +4 -2
- package/dist/esm/commands/includes/moveParentFromWaitingChildrenToFailed.lua +10 -2
- package/dist/esm/commands/includes/removeJobsOnFail.lua +36 -0
- package/dist/esm/commands/moveStalledJobsToWait-9.lua +2 -27
- package/dist/esm/scripts/addJobScheduler-2.js +4 -2
- package/dist/esm/scripts/addJobScheduler-2.js.map +1 -1
- package/dist/esm/scripts/moveStalledJobsToWait-9.js +68 -56
- package/dist/esm/scripts/moveStalledJobsToWait-9.js.map +1 -1
- package/dist/esm/scripts/moveToFinished-14.js +143 -110
- package/dist/esm/scripts/moveToFinished-14.js.map +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
@@ -278,117 +278,8 @@ local function removeDeduplicationKeyIfNeeded(prefixKey, deduplicationId)
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
end
|
281
|
-
local function moveParentFromWaitingChildrenToFailed( parentQueueKey, parentKey, parentId, jobIdKey, timestamp)
|
282
|
-
if rcall("ZREM", parentQueueKey .. ":waiting-children", parentId) == 1 then
|
283
|
-
rcall("ZADD", parentQueueKey .. ":failed", timestamp, parentId)
|
284
|
-
local failedReason = "child " .. jobIdKey .. " failed"
|
285
|
-
rcall("HMSET", parentKey, "failedReason", failedReason, "finishedOn", timestamp)
|
286
|
-
rcall("XADD", parentQueueKey .. ":events", "*", "event", "failed", "jobId", parentId, "failedReason",
|
287
|
-
failedReason, "prev", "waiting-children")
|
288
|
-
local jobAttributes = rcall("HMGET", parentKey, "parent", "deid")
|
289
|
-
removeDeduplicationKeyIfNeeded(parentQueueKey .. ":", jobAttributes[2])
|
290
|
-
if jobAttributes[1] then
|
291
|
-
local parentData = cjson.decode(jobAttributes[1])
|
292
|
-
if parentData['fpof'] then
|
293
|
-
moveParentFromWaitingChildrenToFailed(
|
294
|
-
parentData['queueKey'],
|
295
|
-
parentData['queueKey'] .. ':' .. parentData['id'],
|
296
|
-
parentData['id'],
|
297
|
-
parentKey,
|
298
|
-
timestamp
|
299
|
-
)
|
300
|
-
elseif parentData['idof'] or parentData['rdof'] then
|
301
|
-
local grandParentKey = parentData['queueKey'] .. ':' .. parentData['id']
|
302
|
-
local grandParentDependenciesSet = grandParentKey .. ":dependencies"
|
303
|
-
if rcall("SREM", grandParentDependenciesSet, parentKey) == 1 then
|
304
|
-
moveParentToWaitIfNeeded(parentData['queueKey'], grandParentDependenciesSet,
|
305
|
-
grandParentKey, parentData['id'], timestamp)
|
306
|
-
if parentData['idof'] then
|
307
|
-
local grandParentFailedSet = grandParentKey .. ":failed"
|
308
|
-
rcall("HSET", grandParentFailedSet, parentKey, failedReason)
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
--[[
|
316
|
-
Function to move job from wait state to active.
|
317
|
-
Input:
|
318
|
-
opts - token - lock token
|
319
|
-
opts - lockDuration
|
320
|
-
opts - limiter
|
321
|
-
]]
|
322
|
-
-- Includes
|
323
|
-
local function prepareJobForProcessing(keyPrefix, rateLimiterKey, eventStreamKey,
|
324
|
-
jobId, processedOn, maxJobs, markerKey, opts)
|
325
|
-
local jobKey = keyPrefix .. jobId
|
326
|
-
-- Check if we need to perform rate limiting.
|
327
|
-
if maxJobs then
|
328
|
-
local jobCounter = tonumber(rcall("INCR", rateLimiterKey))
|
329
|
-
if jobCounter == 1 then
|
330
|
-
local limiterDuration = opts['limiter'] and opts['limiter']['duration']
|
331
|
-
local integerDuration = math.floor(math.abs(limiterDuration))
|
332
|
-
rcall("PEXPIRE", rateLimiterKey, integerDuration)
|
333
|
-
end
|
334
|
-
end
|
335
|
-
local lockKey = jobKey .. ':lock'
|
336
|
-
-- get a lock
|
337
|
-
if opts['token'] ~= "0" then
|
338
|
-
rcall("SET", lockKey, opts['token'], "PX", opts['lockDuration'])
|
339
|
-
end
|
340
|
-
local optionalValues = {}
|
341
|
-
if opts['name'] then
|
342
|
-
-- Set "processedBy" field to the worker name
|
343
|
-
table.insert(optionalValues, "pb")
|
344
|
-
table.insert(optionalValues, opts['name'])
|
345
|
-
end
|
346
|
-
rcall("XADD", eventStreamKey, "*", "event", "active", "jobId", jobId, "prev", "waiting")
|
347
|
-
rcall("HMSET", jobKey, "processedOn", processedOn, unpack(optionalValues))
|
348
|
-
rcall("HINCRBY", jobKey, "ats", 1)
|
349
|
-
addBaseMarkerIfNeeded(markerKey, false)
|
350
|
-
return {rcall("HGETALL", jobKey), jobId, 0, 0} -- get job data
|
351
|
-
end
|
352
|
-
--[[
|
353
|
-
Updates the delay set, by moving delayed jobs that should
|
354
|
-
be processed now to "wait".
|
355
|
-
Events:
|
356
|
-
'waiting'
|
357
|
-
]]
|
358
|
-
-- Includes
|
359
|
-
-- Try to get as much as 1000 jobs at once
|
360
|
-
local function promoteDelayedJobs(delayedKey, markerKey, targetKey, prioritizedKey,
|
361
|
-
eventStreamKey, prefix, timestamp, priorityCounterKey, isPaused)
|
362
|
-
local jobs = rcall("ZRANGEBYSCORE", delayedKey, 0, (timestamp + 1) * 0x1000 - 1, "LIMIT", 0, 1000)
|
363
|
-
if (#jobs > 0) then
|
364
|
-
rcall("ZREM", delayedKey, unpack(jobs))
|
365
|
-
for _, jobId in ipairs(jobs) do
|
366
|
-
local jobKey = prefix .. jobId
|
367
|
-
local priority =
|
368
|
-
tonumber(rcall("HGET", jobKey, "priority")) or 0
|
369
|
-
if priority == 0 then
|
370
|
-
-- LIFO or FIFO
|
371
|
-
addJobInTargetList(targetKey, markerKey, "LPUSH", isPaused, jobId)
|
372
|
-
else
|
373
|
-
addJobWithPriority(markerKey, prioritizedKey, priority,
|
374
|
-
jobId, priorityCounterKey, isPaused)
|
375
|
-
end
|
376
|
-
-- Emit waiting event
|
377
|
-
rcall("XADD", eventStreamKey, "*", "event", "waiting", "jobId",
|
378
|
-
jobId, "prev", "delayed")
|
379
|
-
rcall("HSET", jobKey, "delay", 0)
|
380
|
-
end
|
381
|
-
end
|
382
|
-
end
|
383
|
-
--[[
|
384
|
-
Function to remove job keys.
|
385
|
-
]]
|
386
|
-
local function removeJobKeys(jobKey)
|
387
|
-
return rcall("DEL", jobKey, jobKey .. ':logs',
|
388
|
-
jobKey .. ':dependencies', jobKey .. ':processed', jobKey .. ':failed')
|
389
|
-
end
|
390
281
|
--[[
|
391
|
-
Functions to remove jobs
|
282
|
+
Functions to remove jobs when removeOnFail option is provided.
|
392
283
|
]]
|
393
284
|
-- Includes
|
394
285
|
--[[
|
@@ -405,6 +296,13 @@ local function removeDeduplicationKey(prefixKey, jobKey)
|
|
405
296
|
rcall("DEL", deduplicationKey)
|
406
297
|
end
|
407
298
|
end
|
299
|
+
--[[
|
300
|
+
Function to remove job keys.
|
301
|
+
]]
|
302
|
+
local function removeJobKeys(jobKey)
|
303
|
+
return rcall("DEL", jobKey, jobKey .. ':logs',
|
304
|
+
jobKey .. ':dependencies', jobKey .. ':processed', jobKey .. ':failed')
|
305
|
+
end
|
408
306
|
--[[
|
409
307
|
Check if this job has a parent. If so we will just remove it from
|
410
308
|
the parent child list, but if it is the last child we should move the parent to "wait/paused"
|
@@ -501,6 +399,10 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
|
501
399
|
end
|
502
400
|
removeJobKeys(jobKey)
|
503
401
|
end
|
402
|
+
--[[
|
403
|
+
Functions to remove jobs by max age.
|
404
|
+
]]
|
405
|
+
-- Includes
|
504
406
|
local function removeJobsByMaxAge(timestamp, maxAge, targetSet, prefix,
|
505
407
|
shouldRemoveDebounceKey)
|
506
408
|
local start = timestamp - maxAge * 1000
|
@@ -522,6 +424,137 @@ local function removeJobsByMaxCount(maxCount, targetSet, prefix)
|
|
522
424
|
end
|
523
425
|
rcall("ZREMRANGEBYRANK", targetSet, 0, -(maxCount + 1))
|
524
426
|
end
|
427
|
+
local function removeJobsOnFail(queueKeyPrefix, failedKey, jobId, opts, timestamp)
|
428
|
+
local removeOnFailType = type(opts["removeOnFail"])
|
429
|
+
if removeOnFailType == "number" then
|
430
|
+
removeJobsByMaxCount(opts["removeOnFail"],
|
431
|
+
failedKey, queueKeyPrefix)
|
432
|
+
elseif removeOnFailType == "boolean" then
|
433
|
+
if opts["removeOnFail"] then
|
434
|
+
removeJob(jobId, false, queueKeyPrefix,
|
435
|
+
false --[[remove debounce key]])
|
436
|
+
rcall("ZREM", failedKey, jobId)
|
437
|
+
end
|
438
|
+
elseif removeOnFailType ~= "nil" then
|
439
|
+
local maxAge = opts["removeOnFail"]["age"]
|
440
|
+
local maxCount = opts["removeOnFail"]["count"]
|
441
|
+
if maxAge ~= nil then
|
442
|
+
removeJobsByMaxAge(timestamp, maxAge,
|
443
|
+
failedKey, queueKeyPrefix)
|
444
|
+
end
|
445
|
+
if maxCount ~= nil and maxCount > 0 then
|
446
|
+
removeJobsByMaxCount(maxCount, failedKey,
|
447
|
+
queueKeyPrefix)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
local function moveParentFromWaitingChildrenToFailed( parentQueueKey, parentKey, parentId, jobIdKey, timestamp)
|
452
|
+
if rcall("ZREM", parentQueueKey .. ":waiting-children", parentId) == 1 then
|
453
|
+
local parentQueuePrefix = parentQueueKey .. ":"
|
454
|
+
local parentFailedKey = parentQueueKey .. ":failed"
|
455
|
+
rcall("ZADD", parentFailedKey, timestamp, parentId)
|
456
|
+
local failedReason = "child " .. jobIdKey .. " failed"
|
457
|
+
rcall("HMSET", parentKey, "failedReason", failedReason, "finishedOn", timestamp)
|
458
|
+
rcall("XADD", parentQueueKey .. ":events", "*", "event", "failed", "jobId", parentId, "failedReason",
|
459
|
+
failedReason, "prev", "waiting-children")
|
460
|
+
local jobAttributes = rcall("HMGET", parentKey, "parent", "deid", "opts")
|
461
|
+
removeDeduplicationKeyIfNeeded(parentQueueKey .. ":", jobAttributes[2])
|
462
|
+
if jobAttributes[1] then
|
463
|
+
local parentData = cjson.decode(jobAttributes[1])
|
464
|
+
if parentData['fpof'] then
|
465
|
+
moveParentFromWaitingChildrenToFailed(
|
466
|
+
parentData['queueKey'],
|
467
|
+
parentData['queueKey'] .. ':' .. parentData['id'],
|
468
|
+
parentData['id'],
|
469
|
+
parentKey,
|
470
|
+
timestamp
|
471
|
+
)
|
472
|
+
elseif parentData['idof'] or parentData['rdof'] then
|
473
|
+
local grandParentKey = parentData['queueKey'] .. ':' .. parentData['id']
|
474
|
+
local grandParentDependenciesSet = grandParentKey .. ":dependencies"
|
475
|
+
if rcall("SREM", grandParentDependenciesSet, parentKey) == 1 then
|
476
|
+
moveParentToWaitIfNeeded(parentData['queueKey'], grandParentDependenciesSet,
|
477
|
+
grandParentKey, parentData['id'], timestamp)
|
478
|
+
if parentData['idof'] then
|
479
|
+
local grandParentFailedSet = grandParentKey .. ":failed"
|
480
|
+
rcall("HSET", grandParentFailedSet, parentKey, failedReason)
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
local parentRawOpts = jobAttributes[3]
|
486
|
+
local parentOpts = cjson.decode(parentRawOpts)
|
487
|
+
removeJobsOnFail(parentQueuePrefix, parentFailedKey, parentId, parentOpts, timestamp)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
--[[
|
491
|
+
Function to move job from wait state to active.
|
492
|
+
Input:
|
493
|
+
opts - token - lock token
|
494
|
+
opts - lockDuration
|
495
|
+
opts - limiter
|
496
|
+
]]
|
497
|
+
-- Includes
|
498
|
+
local function prepareJobForProcessing(keyPrefix, rateLimiterKey, eventStreamKey,
|
499
|
+
jobId, processedOn, maxJobs, markerKey, opts)
|
500
|
+
local jobKey = keyPrefix .. jobId
|
501
|
+
-- Check if we need to perform rate limiting.
|
502
|
+
if maxJobs then
|
503
|
+
local jobCounter = tonumber(rcall("INCR", rateLimiterKey))
|
504
|
+
if jobCounter == 1 then
|
505
|
+
local limiterDuration = opts['limiter'] and opts['limiter']['duration']
|
506
|
+
local integerDuration = math.floor(math.abs(limiterDuration))
|
507
|
+
rcall("PEXPIRE", rateLimiterKey, integerDuration)
|
508
|
+
end
|
509
|
+
end
|
510
|
+
local lockKey = jobKey .. ':lock'
|
511
|
+
-- get a lock
|
512
|
+
if opts['token'] ~= "0" then
|
513
|
+
rcall("SET", lockKey, opts['token'], "PX", opts['lockDuration'])
|
514
|
+
end
|
515
|
+
local optionalValues = {}
|
516
|
+
if opts['name'] then
|
517
|
+
-- Set "processedBy" field to the worker name
|
518
|
+
table.insert(optionalValues, "pb")
|
519
|
+
table.insert(optionalValues, opts['name'])
|
520
|
+
end
|
521
|
+
rcall("XADD", eventStreamKey, "*", "event", "active", "jobId", jobId, "prev", "waiting")
|
522
|
+
rcall("HMSET", jobKey, "processedOn", processedOn, unpack(optionalValues))
|
523
|
+
rcall("HINCRBY", jobKey, "ats", 1)
|
524
|
+
addBaseMarkerIfNeeded(markerKey, false)
|
525
|
+
return {rcall("HGETALL", jobKey), jobId, 0, 0} -- get job data
|
526
|
+
end
|
527
|
+
--[[
|
528
|
+
Updates the delay set, by moving delayed jobs that should
|
529
|
+
be processed now to "wait".
|
530
|
+
Events:
|
531
|
+
'waiting'
|
532
|
+
]]
|
533
|
+
-- Includes
|
534
|
+
-- Try to get as much as 1000 jobs at once
|
535
|
+
local function promoteDelayedJobs(delayedKey, markerKey, targetKey, prioritizedKey,
|
536
|
+
eventStreamKey, prefix, timestamp, priorityCounterKey, isPaused)
|
537
|
+
local jobs = rcall("ZRANGEBYSCORE", delayedKey, 0, (timestamp + 1) * 0x1000 - 1, "LIMIT", 0, 1000)
|
538
|
+
if (#jobs > 0) then
|
539
|
+
rcall("ZREM", delayedKey, unpack(jobs))
|
540
|
+
for _, jobId in ipairs(jobs) do
|
541
|
+
local jobKey = prefix .. jobId
|
542
|
+
local priority =
|
543
|
+
tonumber(rcall("HGET", jobKey, "priority")) or 0
|
544
|
+
if priority == 0 then
|
545
|
+
-- LIFO or FIFO
|
546
|
+
addJobInTargetList(targetKey, markerKey, "LPUSH", isPaused, jobId)
|
547
|
+
else
|
548
|
+
addJobWithPriority(markerKey, prioritizedKey, priority,
|
549
|
+
jobId, priorityCounterKey, isPaused)
|
550
|
+
end
|
551
|
+
-- Emit waiting event
|
552
|
+
rcall("XADD", eventStreamKey, "*", "event", "waiting", "jobId",
|
553
|
+
jobId, "prev", "delayed")
|
554
|
+
rcall("HSET", jobKey, "delay", 0)
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
525
558
|
local function removeLock(jobKey, stalledKey, token, jobId)
|
526
559
|
if token ~= "0" then
|
527
560
|
local lockKey = jobKey .. ':lock'
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"moveToFinished-14.js","sourceRoot":"","sources":["../../../src/scripts/moveToFinished-14.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG
|
1
|
+
{"version":3,"file":"moveToFinished-14.js","sourceRoot":"","sources":["../../../src/scripts/moveToFinished-14.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuwBf,CAAC;AACW,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,gBAAgB;IACtB,OAAO;IACP,IAAI,EAAE,EAAE;CACT,CAAC"}
|