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