bullmq 5.49.1 → 5.50.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.
- package/dist/cjs/classes/job.js +23 -18
- package/dist/cjs/classes/job.js.map +1 -1
- package/dist/cjs/classes/queue.js +0 -1
- package/dist/cjs/classes/queue.js.map +1 -1
- package/dist/cjs/classes/worker.js +4 -0
- package/dist/cjs/classes/worker.js.map +1 -1
- package/dist/cjs/commands/includes/moveChildFromDependenciesIfNeeded.lua +15 -32
- package/dist/cjs/commands/includes/moveParentToWait.lua +32 -33
- package/dist/cjs/commands/includes/moveParentToWaitIfNeeded.lua +8 -4
- package/dist/cjs/commands/includes/moveParentToWaitIfNoPendingDependencies.lua +13 -0
- package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeededOnFinalization.lua +23 -0
- package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeededOnRemoval.lua +16 -0
- package/dist/cjs/commands/includes/removeJob.lua +2 -2
- package/dist/cjs/commands/includes/removeJobWithChildren.lua +2 -2
- package/dist/cjs/commands/includes/updateParentDepsIfNeeded.lua +2 -2
- package/dist/cjs/commands/moveStalledJobsToWait-9.lua +2 -4
- package/dist/cjs/commands/moveToFinished-14.lua +7 -5
- package/dist/cjs/commands/moveToWaitingChildren-8.lua +2 -4
- package/dist/cjs/scripts/addDelayedJob-6.js +51 -37
- package/dist/cjs/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/cjs/scripts/addJobScheduler-11.js +9 -4
- package/dist/cjs/scripts/addJobScheduler-11.js.map +1 -1
- package/dist/cjs/scripts/addParentJob-4.js +51 -37
- package/dist/cjs/scripts/addParentJob-4.js.map +1 -1
- package/dist/cjs/scripts/addPrioritizedJob-8.js +51 -37
- package/dist/cjs/scripts/addPrioritizedJob-8.js.map +1 -1
- package/dist/cjs/scripts/addRepeatableJob-2.js +9 -4
- package/dist/cjs/scripts/addRepeatableJob-2.js.map +1 -1
- package/dist/cjs/scripts/addStandardJob-8.js +51 -37
- package/dist/cjs/scripts/addStandardJob-8.js.map +1 -1
- package/dist/cjs/scripts/cleanJobsInSet-3.js +9 -4
- package/dist/cjs/scripts/cleanJobsInSet-3.js.map +1 -1
- package/dist/cjs/scripts/drain-5.js +9 -4
- package/dist/cjs/scripts/drain-5.js.map +1 -1
- package/dist/cjs/scripts/moveStalledJobsToWait-9.js +92 -76
- package/dist/cjs/scripts/moveStalledJobsToWait-9.js.map +1 -1
- package/dist/cjs/scripts/moveToFinished-14.js +97 -78
- package/dist/cjs/scripts/moveToFinished-14.js.map +1 -1
- package/dist/cjs/scripts/moveToWaitingChildren-8.js +92 -76
- package/dist/cjs/scripts/moveToWaitingChildren-8.js.map +1 -1
- package/dist/cjs/scripts/obliterate-2.js +9 -4
- package/dist/cjs/scripts/obliterate-2.js.map +1 -1
- package/dist/cjs/scripts/removeJob-3.js +9 -4
- package/dist/cjs/scripts/removeJob-3.js.map +1 -1
- package/dist/cjs/scripts/removeUnprocessedChildren-2.js +9 -4
- package/dist/cjs/scripts/removeUnprocessedChildren-2.js.map +1 -1
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils.js +11 -1
- package/dist/cjs/utils.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/classes/job.d.ts +21 -4
- package/dist/esm/classes/job.js +24 -19
- package/dist/esm/classes/job.js.map +1 -1
- package/dist/esm/classes/queue.d.ts +0 -1
- package/dist/esm/classes/queue.js +0 -1
- package/dist/esm/classes/queue.js.map +1 -1
- package/dist/esm/classes/worker.js +5 -1
- package/dist/esm/classes/worker.js.map +1 -1
- package/dist/esm/commands/includes/moveChildFromDependenciesIfNeeded.lua +15 -32
- package/dist/esm/commands/includes/moveParentToWait.lua +32 -33
- package/dist/esm/commands/includes/moveParentToWaitIfNeeded.lua +8 -4
- package/dist/esm/commands/includes/moveParentToWaitIfNoPendingDependencies.lua +13 -0
- package/dist/esm/commands/includes/removeDeduplicationKeyIfNeededOnFinalization.lua +23 -0
- package/dist/esm/commands/includes/removeDeduplicationKeyIfNeededOnRemoval.lua +16 -0
- package/dist/esm/commands/includes/removeJob.lua +2 -2
- package/dist/esm/commands/includes/removeJobWithChildren.lua +2 -2
- package/dist/esm/commands/includes/updateParentDepsIfNeeded.lua +2 -2
- package/dist/esm/commands/moveStalledJobsToWait-9.lua +2 -4
- package/dist/esm/commands/moveToFinished-14.lua +7 -5
- package/dist/esm/commands/moveToWaitingChildren-8.lua +2 -4
- package/dist/esm/interfaces/job-json.d.ts +1 -0
- package/dist/esm/scripts/addDelayedJob-6.js +51 -37
- package/dist/esm/scripts/addDelayedJob-6.js.map +1 -1
- package/dist/esm/scripts/addJobScheduler-11.js +9 -4
- package/dist/esm/scripts/addJobScheduler-11.js.map +1 -1
- package/dist/esm/scripts/addParentJob-4.js +51 -37
- package/dist/esm/scripts/addParentJob-4.js.map +1 -1
- package/dist/esm/scripts/addPrioritizedJob-8.js +51 -37
- package/dist/esm/scripts/addPrioritizedJob-8.js.map +1 -1
- package/dist/esm/scripts/addRepeatableJob-2.js +9 -4
- package/dist/esm/scripts/addRepeatableJob-2.js.map +1 -1
- package/dist/esm/scripts/addStandardJob-8.js +51 -37
- package/dist/esm/scripts/addStandardJob-8.js.map +1 -1
- package/dist/esm/scripts/cleanJobsInSet-3.js +9 -4
- package/dist/esm/scripts/cleanJobsInSet-3.js.map +1 -1
- package/dist/esm/scripts/drain-5.js +9 -4
- package/dist/esm/scripts/drain-5.js.map +1 -1
- package/dist/esm/scripts/moveStalledJobsToWait-9.js +92 -76
- package/dist/esm/scripts/moveStalledJobsToWait-9.js.map +1 -1
- package/dist/esm/scripts/moveToFinished-14.js +97 -78
- package/dist/esm/scripts/moveToFinished-14.js.map +1 -1
- package/dist/esm/scripts/moveToWaitingChildren-8.js +92 -76
- package/dist/esm/scripts/moveToWaitingChildren-8.js.map +1 -1
- package/dist/esm/scripts/obliterate-2.js +9 -4
- package/dist/esm/scripts/obliterate-2.js.map +1 -1
- package/dist/esm/scripts/removeJob-3.js +9 -4
- package/dist/esm/scripts/removeJob-3.js.map +1 -1
- package/dist/esm/scripts/removeUnprocessedChildren-2.js +9 -4
- package/dist/esm/scripts/removeUnprocessedChildren-2.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +17 -0
- package/dist/esm/utils.js +10 -0
- package/dist/esm/utils.js.map +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/commands/includes/removeDeduplicationKey.lua +0 -11
- package/dist/cjs/commands/includes/removeDeduplicationKeyIfNeeded.lua +0 -14
- package/dist/esm/commands/includes/removeDeduplicationKey.lua +0 -11
- package/dist/esm/commands/includes/removeDeduplicationKeyIfNeeded.lua +0 -14
@@ -167,12 +167,19 @@ end
|
|
167
167
|
Function to recursively move from waitingChildren to failed.
|
168
168
|
]]
|
169
169
|
-- Includes
|
170
|
+
--[[
|
171
|
+
Validate and move parent to a wait status (waiting, delayed or prioritized)
|
172
|
+
if no pending dependencies.
|
173
|
+
]]
|
174
|
+
-- Includes
|
170
175
|
--[[
|
171
176
|
Validate and move parent to a wait status (waiting, delayed or prioritized) if needed.
|
172
177
|
]]
|
178
|
+
-- Includes
|
173
179
|
--[[
|
174
|
-
|
180
|
+
Move parent to a wait status (wait, prioritized or delayed)
|
175
181
|
]]
|
182
|
+
-- Includes
|
176
183
|
--[[
|
177
184
|
Add delay marker if needed.
|
178
185
|
]]
|
@@ -235,57 +242,52 @@ local function isQueuePausedOrMaxed(queueMetaKey, activeKey)
|
|
235
242
|
return false
|
236
243
|
end
|
237
244
|
local function moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
238
|
-
local
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
245
|
+
local parentWaitKey = parentQueueKey .. ":wait"
|
246
|
+
local parentPausedKey = parentQueueKey .. ":paused"
|
247
|
+
local parentActiveKey = parentQueueKey .. ":active"
|
248
|
+
local parentMetaKey = parentQueueKey .. ":meta"
|
249
|
+
local parentMarkerKey = parentQueueKey .. ":marker"
|
250
|
+
local jobAttributes = rcall("HMGET", parentKey, "priority", "delay")
|
251
|
+
local priority = tonumber(jobAttributes[1]) or 0
|
252
|
+
local delay = tonumber(jobAttributes[2]) or 0
|
253
|
+
-- ignore dependencies if any left
|
254
|
+
rcall("HSET", parentKey, "igdp", 1)
|
255
|
+
if delay > 0 then
|
256
|
+
local delayedTimestamp = tonumber(timestamp) + delay
|
257
|
+
local score = delayedTimestamp * 0x1000
|
258
|
+
local parentDelayedKey = parentQueueKey .. ":delayed"
|
259
|
+
rcall("ZADD", parentDelayedKey, score, parentId)
|
260
|
+
rcall("XADD", parentQueueKey .. ":events", "*", "event", "delayed", "jobId", parentId, "delay",
|
261
|
+
delayedTimestamp)
|
262
|
+
addDelayMarkerIfNeeded(parentMarkerKey, parentDelayedKey)
|
263
|
+
else
|
264
|
+
if priority == 0 then
|
265
|
+
local parentTarget, isParentPausedOrMaxed = getTargetQueueList(parentMetaKey, parentActiveKey,
|
266
|
+
parentWaitKey, parentPausedKey)
|
267
|
+
addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed, parentId)
|
258
268
|
else
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed, parentId)
|
263
|
-
else
|
264
|
-
local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
|
265
|
-
addJobWithPriority(parentMarkerKey, parentQueueKey .. ":prioritized", priority, parentId,
|
266
|
-
parentQueueKey .. ":pc", isPausedOrMaxed)
|
267
|
-
end
|
268
|
-
rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev",
|
269
|
-
"waiting-children")
|
269
|
+
local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
|
270
|
+
addJobWithPriority(parentMarkerKey, parentQueueKey .. ":prioritized", priority, parentId,
|
271
|
+
parentQueueKey .. ":pc", isPausedOrMaxed)
|
270
272
|
end
|
273
|
+
rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev",
|
274
|
+
"waiting-children")
|
271
275
|
end
|
272
276
|
end
|
273
|
-
local function moveParentToWaitIfNeeded(parentQueueKey,
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
+
local function moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
|
278
|
+
if rcall("EXISTS", parentKey) == 1 then
|
279
|
+
local parentWaitingChildrenKey = parentQueueKey .. ":waiting-children"
|
280
|
+
if rcall("ZSCORE", parentWaitingChildrenKey, parentId) then
|
281
|
+
rcall("ZREM", parentWaitingChildrenKey, parentId)
|
282
|
+
moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
277
283
|
end
|
284
|
+
end
|
278
285
|
end
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
285
|
-
local pttl = rcall("PTTL", deduplicationKey)
|
286
|
-
if pttl == 0 or pttl == -1 then
|
287
|
-
rcall("DEL", deduplicationKey)
|
288
|
-
end
|
286
|
+
local function moveParentToWaitIfNoPendingDependencies(parentQueueKey, parentDependenciesKey, parentKey,
|
287
|
+
parentId, timestamp)
|
288
|
+
local doNotHavePendingDependencies = rcall("SCARD", parentDependenciesKey) == 0
|
289
|
+
if doNotHavePendingDependencies then
|
290
|
+
moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
|
289
291
|
end
|
290
292
|
end
|
291
293
|
--[[
|
@@ -297,13 +299,18 @@ end
|
|
297
299
|
]]
|
298
300
|
-- Includes
|
299
301
|
--[[
|
300
|
-
Function to remove deduplication key
|
302
|
+
Function to remove deduplication key if needed
|
303
|
+
when a job is being removed.
|
301
304
|
]]
|
302
|
-
local function
|
305
|
+
local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
|
306
|
+
jobKey, jobId)
|
303
307
|
local deduplicationId = rcall("HGET", jobKey, "deid")
|
304
308
|
if deduplicationId then
|
305
309
|
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
306
|
-
rcall(
|
310
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
311
|
+
if currentJobId and currentJobId == jobId then
|
312
|
+
return rcall("DEL", deduplicationKey)
|
313
|
+
end
|
307
314
|
end
|
308
315
|
end
|
309
316
|
--[[
|
@@ -405,7 +412,7 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
|
405
412
|
local jobKey = baseKey .. jobId
|
406
413
|
removeParentDependencyKey(jobKey, hard, nil, baseKey)
|
407
414
|
if shouldRemoveDeduplicationKey then
|
408
|
-
|
415
|
+
removeDeduplicationKeyIfNeededOnRemoval(baseKey, jobKey, jobId)
|
409
416
|
end
|
410
417
|
removeJobKeys(jobKey)
|
411
418
|
end
|
@@ -465,38 +472,27 @@ moveParentToFailedIfNeeded = function (parentQueueKey, parentKey, parentId, jobI
|
|
465
472
|
local parentWaitingChildrenKey = parentQueueKey .. ":waiting-children"
|
466
473
|
local parentDelayedKey = parentQueueKey .. ":delayed"
|
467
474
|
local parentPrioritizedKey = parentQueueKey .. ":prioritized"
|
468
|
-
local
|
475
|
+
local parentWaitingChildrenOrDelayedKey
|
469
476
|
local prevState
|
470
477
|
if rcall("ZSCORE", parentWaitingChildrenKey, parentId) then
|
471
|
-
|
478
|
+
parentWaitingChildrenOrDelayedKey = parentWaitingChildrenKey
|
472
479
|
prevState = "waiting-children"
|
473
480
|
elseif rcall("ZSCORE", parentDelayedKey, parentId) then
|
474
|
-
|
481
|
+
parentWaitingChildrenOrDelayedKey = parentDelayedKey
|
475
482
|
prevState = "delayed"
|
476
|
-
|
477
|
-
parentWaitingChildrenOrDelayedOrPrioritizedKey = parentPrioritizedKey
|
478
|
-
prevState = "prioritized"
|
483
|
+
rcall("HSET", parentKey, "delay", 0)
|
479
484
|
end
|
480
|
-
if
|
481
|
-
rcall("ZREM",
|
485
|
+
if parentWaitingChildrenOrDelayedKey then
|
486
|
+
rcall("ZREM", parentWaitingChildrenOrDelayedKey, parentId)
|
482
487
|
local parentQueuePrefix = parentQueueKey .. ":"
|
483
488
|
local parentFailedKey = parentQueueKey .. ":failed"
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
rcall("XADD", parentQueueKey .. ":events", "*", "event", "failed", "jobId", parentId, "failedReason",
|
488
|
-
failedReason, "prev", prevState)
|
489
|
-
local jobAttributes = rcall("HMGET", parentKey, "parent", "deid", "opts")
|
490
|
-
removeDeduplicationKeyIfNeeded(parentQueueKey .. ":", jobAttributes[2])
|
491
|
-
moveChildFromDependenciesIfNeeded(jobAttributes[1], parentKey, failedReason, timestamp)
|
492
|
-
local parentRawOpts = jobAttributes[3]
|
493
|
-
local parentOpts = cjson.decode(parentRawOpts)
|
494
|
-
removeJobsOnFail(parentQueuePrefix, parentFailedKey, parentId, parentOpts, timestamp)
|
489
|
+
local deferredFailure = "child " .. jobIdKey .. " failed"
|
490
|
+
rcall("HSET", parentKey, "defa", deferredFailure)
|
491
|
+
moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
495
492
|
else
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
rcall("ZADD", grandParentUnsuccesssfulSet, timestamp, parentKey)
|
493
|
+
if not rcall("ZSCORE", parentQueueKey .. ":failed", parentId) then
|
494
|
+
local deferredFailure = "child " .. jobIdKey .. " failed"
|
495
|
+
rcall("HSET", parentKey, "defa", deferredFailure)
|
500
496
|
end
|
501
497
|
end
|
502
498
|
end
|
@@ -522,11 +518,11 @@ moveChildFromDependenciesIfNeeded = function (rawParentData, childKey, failedRea
|
|
522
518
|
if rcall("SREM", parentDependenciesChildrenKey, childKey) == 1 then
|
523
519
|
local parentFailedChildrenKey = parentKey .. ":failed"
|
524
520
|
rcall("HSET", parentFailedChildrenKey, childKey, failedReason)
|
525
|
-
|
521
|
+
moveParentToWaitIfNeeded(parentData['queueKey'], parentKey, parentData['id'], timestamp)
|
526
522
|
end
|
527
523
|
elseif parentData['idof'] or parentData['rdof'] then
|
528
524
|
if rcall("SREM", parentDependenciesChildrenKey, childKey) == 1 then
|
529
|
-
|
525
|
+
moveParentToWaitIfNoPendingDependencies(parentData['queueKey'], parentDependenciesChildrenKey,
|
530
526
|
parentKey, parentData['id'], timestamp)
|
531
527
|
if parentData['idof'] then
|
532
528
|
local parentFailedChildrenKey = parentKey .. ":failed"
|
@@ -605,6 +601,26 @@ local function promoteDelayedJobs(delayedKey, markerKey, targetKey, prioritizedK
|
|
605
601
|
addBaseMarkerIfNeeded(markerKey, isPaused)
|
606
602
|
end
|
607
603
|
end
|
604
|
+
--[[
|
605
|
+
Function to remove deduplication key if needed
|
606
|
+
when a job is moved to completed or failed states.
|
607
|
+
]]
|
608
|
+
local function removeDeduplicationKeyIfNeededOnFinalization(prefixKey,
|
609
|
+
deduplicationId, jobId)
|
610
|
+
if deduplicationId then
|
611
|
+
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
612
|
+
local pttl = rcall("PTTL", deduplicationKey)
|
613
|
+
if pttl == 0 then
|
614
|
+
return rcall("DEL", deduplicationKey)
|
615
|
+
end
|
616
|
+
if pttl == -1 then
|
617
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
618
|
+
if currentJobId and currentJobId == jobId then
|
619
|
+
return rcall("DEL", deduplicationKey)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
end
|
608
624
|
local function removeLock(jobKey, stalledKey, token, jobId)
|
609
625
|
if token ~= "0" then
|
610
626
|
local lockKey = jobKey .. ':lock'
|
@@ -655,7 +671,7 @@ local function updateParentDepsIfNeeded(parentKey, parentQueueKey, parentDepende
|
|
655
671
|
parentId, jobIdKey, returnvalue, timestamp )
|
656
672
|
local processedSet = parentKey .. ":processed"
|
657
673
|
rcall("HSET", processedSet, jobIdKey, returnvalue)
|
658
|
-
|
674
|
+
moveParentToWaitIfNoPendingDependencies(parentQueueKey, parentDependenciesKey, parentKey, parentId, timestamp)
|
659
675
|
end
|
660
676
|
--[[
|
661
677
|
Function to update a bunch of fields in a job.
|
@@ -709,7 +725,7 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
709
725
|
-- Trim events before emiting them to avoid trimming events emitted in this script
|
710
726
|
trimEvents(metaKey, eventStreamKey)
|
711
727
|
local prefix = ARGV[7]
|
712
|
-
|
728
|
+
removeDeduplicationKeyIfNeededOnFinalization(prefix, jobAttributes[3], jobId)
|
713
729
|
-- If job has a parent we need to
|
714
730
|
-- 1) remove this job id from parents dependencies
|
715
731
|
-- 2) move the job Id to parent "processed" set
|
@@ -736,8 +752,11 @@ if rcall("EXISTS", jobIdKey) == 1 then -- Make sure job exists
|
|
736
752
|
local targetSet = KEYS[11]
|
737
753
|
-- Add to complete/failed set
|
738
754
|
rcall("ZADD", targetSet, timestamp, jobId)
|
739
|
-
rcall("
|
755
|
+
rcall("HSET", jobIdKey, ARGV[3], ARGV[4], "finishedOn", timestamp)
|
740
756
|
-- "returnvalue" / "failedReason" and "finishedOn"
|
757
|
+
if ARGV[5] == "failed" then
|
758
|
+
rcall("HDEL", jobIdKey, "defa")
|
759
|
+
end
|
741
760
|
-- Remove old jobs?
|
742
761
|
if maxAge ~= nil then
|
743
762
|
removeJobsByMaxAge(timestamp, maxAge, targetSet, prefix)
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAi1Bf,CAAC;AACF,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,gBAAgB;IACtB,OAAO;IACP,IAAI,EAAE,EAAE;CACT,CAAC"}
|
@@ -36,12 +36,19 @@ local jobId = ARGV[4]
|
|
36
36
|
Function to recursively move from waitingChildren to failed.
|
37
37
|
]]
|
38
38
|
-- Includes
|
39
|
+
--[[
|
40
|
+
Validate and move parent to a wait status (waiting, delayed or prioritized)
|
41
|
+
if no pending dependencies.
|
42
|
+
]]
|
43
|
+
-- Includes
|
39
44
|
--[[
|
40
45
|
Validate and move parent to a wait status (waiting, delayed or prioritized) if needed.
|
41
46
|
]]
|
47
|
+
-- Includes
|
42
48
|
--[[
|
43
|
-
|
49
|
+
Move parent to a wait status (wait, prioritized or delayed)
|
44
50
|
]]
|
51
|
+
-- Includes
|
45
52
|
--[[
|
46
53
|
Add delay marker if needed.
|
47
54
|
]]
|
@@ -136,57 +143,52 @@ local function getTargetQueueList(queueMetaKey, activeKey, waitKey, pausedKey)
|
|
136
143
|
return waitKey, false
|
137
144
|
end
|
138
145
|
local function moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
139
|
-
local
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
146
|
+
local parentWaitKey = parentQueueKey .. ":wait"
|
147
|
+
local parentPausedKey = parentQueueKey .. ":paused"
|
148
|
+
local parentActiveKey = parentQueueKey .. ":active"
|
149
|
+
local parentMetaKey = parentQueueKey .. ":meta"
|
150
|
+
local parentMarkerKey = parentQueueKey .. ":marker"
|
151
|
+
local jobAttributes = rcall("HMGET", parentKey, "priority", "delay")
|
152
|
+
local priority = tonumber(jobAttributes[1]) or 0
|
153
|
+
local delay = tonumber(jobAttributes[2]) or 0
|
154
|
+
-- ignore dependencies if any left
|
155
|
+
rcall("HSET", parentKey, "igdp", 1)
|
156
|
+
if delay > 0 then
|
157
|
+
local delayedTimestamp = tonumber(timestamp) + delay
|
158
|
+
local score = delayedTimestamp * 0x1000
|
159
|
+
local parentDelayedKey = parentQueueKey .. ":delayed"
|
160
|
+
rcall("ZADD", parentDelayedKey, score, parentId)
|
161
|
+
rcall("XADD", parentQueueKey .. ":events", "*", "event", "delayed", "jobId", parentId, "delay",
|
162
|
+
delayedTimestamp)
|
163
|
+
addDelayMarkerIfNeeded(parentMarkerKey, parentDelayedKey)
|
164
|
+
else
|
165
|
+
if priority == 0 then
|
166
|
+
local parentTarget, isParentPausedOrMaxed = getTargetQueueList(parentMetaKey, parentActiveKey,
|
167
|
+
parentWaitKey, parentPausedKey)
|
168
|
+
addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed, parentId)
|
159
169
|
else
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
addJobInTargetList(parentTarget, parentMarkerKey, "RPUSH", isParentPausedOrMaxed, parentId)
|
164
|
-
else
|
165
|
-
local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
|
166
|
-
addJobWithPriority(parentMarkerKey, parentQueueKey .. ":prioritized", priority, parentId,
|
167
|
-
parentQueueKey .. ":pc", isPausedOrMaxed)
|
168
|
-
end
|
169
|
-
rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev",
|
170
|
-
"waiting-children")
|
170
|
+
local isPausedOrMaxed = isQueuePausedOrMaxed(parentMetaKey, parentActiveKey)
|
171
|
+
addJobWithPriority(parentMarkerKey, parentQueueKey .. ":prioritized", priority, parentId,
|
172
|
+
parentQueueKey .. ":pc", isPausedOrMaxed)
|
171
173
|
end
|
174
|
+
rcall("XADD", parentQueueKey .. ":events", "*", "event", "waiting", "jobId", parentId, "prev",
|
175
|
+
"waiting-children")
|
172
176
|
end
|
173
177
|
end
|
174
|
-
local function moveParentToWaitIfNeeded(parentQueueKey,
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
+
local function moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
|
179
|
+
if rcall("EXISTS", parentKey) == 1 then
|
180
|
+
local parentWaitingChildrenKey = parentQueueKey .. ":waiting-children"
|
181
|
+
if rcall("ZSCORE", parentWaitingChildrenKey, parentId) then
|
182
|
+
rcall("ZREM", parentWaitingChildrenKey, parentId)
|
183
|
+
moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
178
184
|
end
|
185
|
+
end
|
179
186
|
end
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
186
|
-
local pttl = rcall("PTTL", deduplicationKey)
|
187
|
-
if pttl == 0 or pttl == -1 then
|
188
|
-
rcall("DEL", deduplicationKey)
|
189
|
-
end
|
187
|
+
local function moveParentToWaitIfNoPendingDependencies(parentQueueKey, parentDependenciesKey, parentKey,
|
188
|
+
parentId, timestamp)
|
189
|
+
local doNotHavePendingDependencies = rcall("SCARD", parentDependenciesKey) == 0
|
190
|
+
if doNotHavePendingDependencies then
|
191
|
+
moveParentToWaitIfNeeded(parentQueueKey, parentKey, parentId, timestamp)
|
190
192
|
end
|
191
193
|
end
|
192
194
|
--[[
|
@@ -198,13 +200,18 @@ end
|
|
198
200
|
]]
|
199
201
|
-- Includes
|
200
202
|
--[[
|
201
|
-
Function to remove deduplication key
|
203
|
+
Function to remove deduplication key if needed
|
204
|
+
when a job is being removed.
|
202
205
|
]]
|
203
|
-
local function
|
206
|
+
local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
|
207
|
+
jobKey, jobId)
|
204
208
|
local deduplicationId = rcall("HGET", jobKey, "deid")
|
205
209
|
if deduplicationId then
|
206
210
|
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
207
|
-
rcall(
|
211
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
212
|
+
if currentJobId and currentJobId == jobId then
|
213
|
+
return rcall("DEL", deduplicationKey)
|
214
|
+
end
|
208
215
|
end
|
209
216
|
end
|
210
217
|
--[[
|
@@ -306,7 +313,7 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
|
306
313
|
local jobKey = baseKey .. jobId
|
307
314
|
removeParentDependencyKey(jobKey, hard, nil, baseKey)
|
308
315
|
if shouldRemoveDeduplicationKey then
|
309
|
-
|
316
|
+
removeDeduplicationKeyIfNeededOnRemoval(baseKey, jobKey, jobId)
|
310
317
|
end
|
311
318
|
removeJobKeys(jobKey)
|
312
319
|
end
|
@@ -366,38 +373,27 @@ moveParentToFailedIfNeeded = function (parentQueueKey, parentKey, parentId, jobI
|
|
366
373
|
local parentWaitingChildrenKey = parentQueueKey .. ":waiting-children"
|
367
374
|
local parentDelayedKey = parentQueueKey .. ":delayed"
|
368
375
|
local parentPrioritizedKey = parentQueueKey .. ":prioritized"
|
369
|
-
local
|
376
|
+
local parentWaitingChildrenOrDelayedKey
|
370
377
|
local prevState
|
371
378
|
if rcall("ZSCORE", parentWaitingChildrenKey, parentId) then
|
372
|
-
|
379
|
+
parentWaitingChildrenOrDelayedKey = parentWaitingChildrenKey
|
373
380
|
prevState = "waiting-children"
|
374
381
|
elseif rcall("ZSCORE", parentDelayedKey, parentId) then
|
375
|
-
|
382
|
+
parentWaitingChildrenOrDelayedKey = parentDelayedKey
|
376
383
|
prevState = "delayed"
|
377
|
-
|
378
|
-
parentWaitingChildrenOrDelayedOrPrioritizedKey = parentPrioritizedKey
|
379
|
-
prevState = "prioritized"
|
384
|
+
rcall("HSET", parentKey, "delay", 0)
|
380
385
|
end
|
381
|
-
if
|
382
|
-
rcall("ZREM",
|
386
|
+
if parentWaitingChildrenOrDelayedKey then
|
387
|
+
rcall("ZREM", parentWaitingChildrenOrDelayedKey, parentId)
|
383
388
|
local parentQueuePrefix = parentQueueKey .. ":"
|
384
389
|
local parentFailedKey = parentQueueKey .. ":failed"
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
rcall("XADD", parentQueueKey .. ":events", "*", "event", "failed", "jobId", parentId, "failedReason",
|
389
|
-
failedReason, "prev", prevState)
|
390
|
-
local jobAttributes = rcall("HMGET", parentKey, "parent", "deid", "opts")
|
391
|
-
removeDeduplicationKeyIfNeeded(parentQueueKey .. ":", jobAttributes[2])
|
392
|
-
moveChildFromDependenciesIfNeeded(jobAttributes[1], parentKey, failedReason, timestamp)
|
393
|
-
local parentRawOpts = jobAttributes[3]
|
394
|
-
local parentOpts = cjson.decode(parentRawOpts)
|
395
|
-
removeJobsOnFail(parentQueuePrefix, parentFailedKey, parentId, parentOpts, timestamp)
|
390
|
+
local deferredFailure = "child " .. jobIdKey .. " failed"
|
391
|
+
rcall("HSET", parentKey, "defa", deferredFailure)
|
392
|
+
moveParentToWait(parentQueueKey, parentKey, parentId, timestamp)
|
396
393
|
else
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
rcall("ZADD", grandParentUnsuccesssfulSet, timestamp, parentKey)
|
394
|
+
if not rcall("ZSCORE", parentQueueKey .. ":failed", parentId) then
|
395
|
+
local deferredFailure = "child " .. jobIdKey .. " failed"
|
396
|
+
rcall("HSET", parentKey, "defa", deferredFailure)
|
401
397
|
end
|
402
398
|
end
|
403
399
|
end
|
@@ -423,11 +419,11 @@ moveChildFromDependenciesIfNeeded = function (rawParentData, childKey, failedRea
|
|
423
419
|
if rcall("SREM", parentDependenciesChildrenKey, childKey) == 1 then
|
424
420
|
local parentFailedChildrenKey = parentKey .. ":failed"
|
425
421
|
rcall("HSET", parentFailedChildrenKey, childKey, failedReason)
|
426
|
-
|
422
|
+
moveParentToWaitIfNeeded(parentData['queueKey'], parentKey, parentData['id'], timestamp)
|
427
423
|
end
|
428
424
|
elseif parentData['idof'] or parentData['rdof'] then
|
429
425
|
if rcall("SREM", parentDependenciesChildrenKey, childKey) == 1 then
|
430
|
-
|
426
|
+
moveParentToWaitIfNoPendingDependencies(parentData['queueKey'], parentDependenciesChildrenKey,
|
431
427
|
parentKey, parentData['id'], timestamp)
|
432
428
|
if parentData['idof'] then
|
433
429
|
local parentFailedChildrenKey = parentKey .. ":failed"
|
@@ -437,6 +433,26 @@ moveChildFromDependenciesIfNeeded = function (rawParentData, childKey, failedRea
|
|
437
433
|
end
|
438
434
|
end
|
439
435
|
end
|
436
|
+
--[[
|
437
|
+
Function to remove deduplication key if needed
|
438
|
+
when a job is moved to completed or failed states.
|
439
|
+
]]
|
440
|
+
local function removeDeduplicationKeyIfNeededOnFinalization(prefixKey,
|
441
|
+
deduplicationId, jobId)
|
442
|
+
if deduplicationId then
|
443
|
+
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
444
|
+
local pttl = rcall("PTTL", deduplicationKey)
|
445
|
+
if pttl == 0 then
|
446
|
+
return rcall("DEL", deduplicationKey)
|
447
|
+
end
|
448
|
+
if pttl == -1 then
|
449
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
450
|
+
if currentJobId and currentJobId == jobId then
|
451
|
+
return rcall("DEL", deduplicationKey)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
440
456
|
local function removeLock(jobKey, stalledKey, token, jobId)
|
441
457
|
if token ~= "0" then
|
442
458
|
local lockKey = jobKey .. ':lock'
|
@@ -470,7 +486,7 @@ if rcall("EXISTS", jobKey) == 1 then
|
|
470
486
|
if rcall("ZCARD", jobUnsuccessfulKey) ~= 0 then
|
471
487
|
-- TODO: refactor this logic in an include later
|
472
488
|
local jobAttributes = rcall("HMGET", jobKey, "parent", "deid", "opts")
|
473
|
-
|
489
|
+
removeDeduplicationKeyIfNeededOnFinalization(ARGV[5], jobAttributes[2], jobId)
|
474
490
|
local failedReason = "children are failed"
|
475
491
|
rcall("ZADD", failedKey, timestamp, jobId)
|
476
492
|
rcall("HSET", jobKey, "finishedOn", timestamp)
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"moveToWaitingChildren-8.js","sourceRoot":"","sources":["../../../src/scripts/moveToWaitingChildren-8.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG
|
1
|
+
{"version":3,"file":"moveToWaitingChildren-8.js","sourceRoot":"","sources":["../../../src/scripts/moveToWaitingChildren-8.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2gBf,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,uBAAuB;IAC7B,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|
@@ -25,13 +25,18 @@ local rcall = redis.call
|
|
25
25
|
]]
|
26
26
|
-- Includes
|
27
27
|
--[[
|
28
|
-
Function to remove deduplication key
|
28
|
+
Function to remove deduplication key if needed
|
29
|
+
when a job is being removed.
|
29
30
|
]]
|
30
|
-
local function
|
31
|
+
local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
|
32
|
+
jobKey, jobId)
|
31
33
|
local deduplicationId = rcall("HGET", jobKey, "deid")
|
32
34
|
if deduplicationId then
|
33
35
|
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
34
|
-
rcall(
|
36
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
37
|
+
if currentJobId and currentJobId == jobId then
|
38
|
+
return rcall("DEL", deduplicationKey)
|
39
|
+
end
|
35
40
|
end
|
36
41
|
end
|
37
42
|
--[[
|
@@ -169,7 +174,7 @@ local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
|
169
174
|
local jobKey = baseKey .. jobId
|
170
175
|
removeParentDependencyKey(jobKey, hard, nil, baseKey)
|
171
176
|
if shouldRemoveDeduplicationKey then
|
172
|
-
|
177
|
+
removeDeduplicationKeyIfNeededOnRemoval(baseKey, jobKey, jobId)
|
173
178
|
end
|
174
179
|
removeJobKeys(jobKey)
|
175
180
|
end
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"obliterate-2.js","sourceRoot":"","sources":["../../../src/scripts/obliterate-2.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG
|
1
|
+
{"version":3,"file":"obliterate-2.js","sourceRoot":"","sources":["../../../src/scripts/obliterate-2.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Uf,CAAC;AACF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,YAAY;IAClB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|
@@ -88,13 +88,18 @@ local function getOrSetMaxEvents(metaKey)
|
|
88
88
|
return maxEvents
|
89
89
|
end
|
90
90
|
--[[
|
91
|
-
Function to remove deduplication key
|
91
|
+
Function to remove deduplication key if needed
|
92
|
+
when a job is being removed.
|
92
93
|
]]
|
93
|
-
local function
|
94
|
+
local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
|
95
|
+
jobKey, jobId)
|
94
96
|
local deduplicationId = rcall("HGET", jobKey, "deid")
|
95
97
|
if deduplicationId then
|
96
98
|
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
97
|
-
rcall(
|
99
|
+
local currentJobId = rcall('GET', deduplicationKey)
|
100
|
+
if currentJobId and currentJobId == jobId then
|
101
|
+
return rcall("DEL", deduplicationKey)
|
102
|
+
end
|
98
103
|
end
|
99
104
|
end
|
100
105
|
--[[
|
@@ -306,7 +311,7 @@ removeJobWithChildren = function(prefix, meta, jobId, parentKey, options)
|
|
306
311
|
removeJobChildren(prefix, meta, jobKey, options)
|
307
312
|
end
|
308
313
|
local prev = removeJobFromAnyState(prefix, jobId)
|
309
|
-
|
314
|
+
removeDeduplicationKeyIfNeededOnRemoval(prefix, jobKey, jobId)
|
310
315
|
if removeJobKeys(jobKey) > 0 then
|
311
316
|
local maxEvents = getOrSetMaxEvents(meta)
|
312
317
|
rcall("XADD", prefix .. "events", "MAXLEN", "~", maxEvents, "*", "event", "removed",
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"removeJob-3.js","sourceRoot":"","sources":["../../../src/scripts/removeJob-3.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG
|
1
|
+
{"version":3,"file":"removeJob-3.js","sourceRoot":"","sources":["../../../src/scripts/removeJob-3.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoVf,CAAC;AACF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,WAAW;IACjB,OAAO;IACP,IAAI,EAAE,CAAC;CACR,CAAC"}
|