Review funkt
This commit is contained in:
342
node_modules/bullmq/dist/esm/scripts/obliterate-2.js
generated
vendored
Normal file
342
node_modules/bullmq/dist/esm/scripts/obliterate-2.js
generated
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
const content = `--[[
|
||||
Completely obliterates a queue and all of its contents
|
||||
This command completely destroys a queue including all of its jobs, current or past
|
||||
leaving no trace of its existence. Since this script needs to iterate to find all the job
|
||||
keys, consider that this call may be slow for very large queues.
|
||||
The queue needs to be "paused" or it will return an error
|
||||
If the queue has currently active jobs then the script by default will return error,
|
||||
however this behaviour can be overridden using the 'force' option.
|
||||
Input:
|
||||
KEYS[1] meta
|
||||
KEYS[2] base
|
||||
ARGV[1] count
|
||||
ARGV[2] force
|
||||
]]
|
||||
local maxCount = tonumber(ARGV[1])
|
||||
local baseKey = KEYS[2]
|
||||
local rcall = redis.call
|
||||
-- Includes
|
||||
--[[
|
||||
Functions to remove jobs.
|
||||
]]
|
||||
-- Includes
|
||||
--[[
|
||||
Function to remove job.
|
||||
]]
|
||||
-- Includes
|
||||
--[[
|
||||
Function to remove deduplication key if needed
|
||||
when a job is being removed.
|
||||
]]
|
||||
local function removeDeduplicationKeyIfNeededOnRemoval(prefixKey,
|
||||
jobId, deduplicationId)
|
||||
if deduplicationId then
|
||||
local deduplicationKey = prefixKey .. "de:" .. deduplicationId
|
||||
local currentJobId = rcall('GET', deduplicationKey)
|
||||
if currentJobId and currentJobId == jobId then
|
||||
rcall("DEL", deduplicationKey)
|
||||
-- Also clean up any pending dedup-next data for this dedup ID
|
||||
rcall("DEL", prefixKey .. "dn:" .. deduplicationId)
|
||||
return 1
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
Function to remove job keys.
|
||||
]]
|
||||
local function removeJobKeys(jobKey)
|
||||
return rcall("DEL", jobKey, jobKey .. ':logs', jobKey .. ':dependencies',
|
||||
jobKey .. ':processed', jobKey .. ':failed', jobKey .. ':unsuccessful')
|
||||
end
|
||||
--[[
|
||||
Check if this job has a parent. If so we will just remove it from
|
||||
the parent child list, but if it is the last child we should move the parent to "wait/paused"
|
||||
which requires code from "moveToFinished"
|
||||
]]
|
||||
-- Includes
|
||||
--[[
|
||||
Function to add job in target list and add marker if needed.
|
||||
]]
|
||||
-- Includes
|
||||
--[[
|
||||
Add marker if needed when a job is available.
|
||||
]]
|
||||
local function addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
|
||||
if not isPausedOrMaxed then
|
||||
rcall("ZADD", markerKey, 0, "0")
|
||||
end
|
||||
end
|
||||
local function addJobInTargetList(targetKey, markerKey, pushCmd, isPausedOrMaxed, jobId)
|
||||
rcall(pushCmd, targetKey, jobId)
|
||||
addBaseMarkerIfNeeded(markerKey, isPausedOrMaxed)
|
||||
end
|
||||
--[[
|
||||
Functions to destructure job key.
|
||||
Just a bit of warning, these functions may be a bit slow and affect performance significantly.
|
||||
]]
|
||||
local getJobIdFromKey = function (jobKey)
|
||||
return string.match(jobKey, ".*:(.*)")
|
||||
end
|
||||
local getJobKeyPrefix = function (jobKey, jobId)
|
||||
return string.sub(jobKey, 0, #jobKey - #jobId)
|
||||
end
|
||||
--[[
|
||||
Function to check if queue is paused or maxed
|
||||
(since an empty list and !EXISTS are not really the same).
|
||||
]]
|
||||
local function isQueuePausedOrMaxed(queueMetaKey, activeKey)
|
||||
local queueAttributes = rcall("HMGET", queueMetaKey, "paused", "concurrency")
|
||||
if queueAttributes[1] then
|
||||
return true
|
||||
else
|
||||
if queueAttributes[2] then
|
||||
local activeCount = rcall("LLEN", activeKey)
|
||||
return activeCount >= tonumber(queueAttributes[2])
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
local function _moveParentToWait(parentPrefix, parentId, emitEvent)
|
||||
local isPausedOrMaxed =
|
||||
isQueuePausedOrMaxed(parentPrefix .. "meta", parentPrefix .. "active")
|
||||
addJobInTargetList(parentPrefix .. "wait", parentPrefix .. "marker", "RPUSH", isPausedOrMaxed, parentId)
|
||||
if emitEvent then
|
||||
local parentEventStream = parentPrefix .. "events"
|
||||
rcall("XADD", parentEventStream, "*", "event", "waiting", "jobId", parentId, "prev", "waiting-children")
|
||||
end
|
||||
end
|
||||
local function removeParentDependencyKey(jobKey, hard, parentKey, baseKey, debounceId)
|
||||
if parentKey then
|
||||
local parentDependenciesKey = parentKey .. ":dependencies"
|
||||
local result = rcall("SREM", parentDependenciesKey, jobKey)
|
||||
if result > 0 then
|
||||
local pendingDependencies = rcall("SCARD", parentDependenciesKey)
|
||||
if pendingDependencies == 0 then
|
||||
local parentId = getJobIdFromKey(parentKey)
|
||||
local parentPrefix = getJobKeyPrefix(parentKey, parentId)
|
||||
local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
|
||||
if numRemovedElements == 1 then
|
||||
if hard then -- remove parent in same queue
|
||||
if parentPrefix == baseKey then
|
||||
removeParentDependencyKey(parentKey, hard, nil, baseKey, nil)
|
||||
removeJobKeys(parentKey)
|
||||
if debounceId then
|
||||
rcall("DEL", parentPrefix .. "de:" .. debounceId)
|
||||
end
|
||||
else
|
||||
_moveParentToWait(parentPrefix, parentId)
|
||||
end
|
||||
else
|
||||
_moveParentToWait(parentPrefix, parentId, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
else
|
||||
local parentAttributes = rcall("HMGET", jobKey, "parentKey", "deid")
|
||||
local missedParentKey = parentAttributes[1]
|
||||
if( (type(missedParentKey) == "string") and missedParentKey ~= ""
|
||||
and (rcall("EXISTS", missedParentKey) == 1)) then
|
||||
local parentDependenciesKey = missedParentKey .. ":dependencies"
|
||||
local result = rcall("SREM", parentDependenciesKey, jobKey)
|
||||
if result > 0 then
|
||||
local pendingDependencies = rcall("SCARD", parentDependenciesKey)
|
||||
if pendingDependencies == 0 then
|
||||
local parentId = getJobIdFromKey(missedParentKey)
|
||||
local parentPrefix = getJobKeyPrefix(missedParentKey, parentId)
|
||||
local numRemovedElements = rcall("ZREM", parentPrefix .. "waiting-children", parentId)
|
||||
if numRemovedElements == 1 then
|
||||
if hard then
|
||||
if parentPrefix == baseKey then
|
||||
removeParentDependencyKey(missedParentKey, hard, nil, baseKey, nil)
|
||||
removeJobKeys(missedParentKey)
|
||||
if parentAttributes[2] then
|
||||
rcall("DEL", parentPrefix .. "de:" .. parentAttributes[2])
|
||||
end
|
||||
else
|
||||
_moveParentToWait(parentPrefix, parentId)
|
||||
end
|
||||
else
|
||||
_moveParentToWait(parentPrefix, parentId, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
local function removeJob(jobId, hard, baseKey, shouldRemoveDeduplicationKey)
|
||||
local jobKey = baseKey .. jobId
|
||||
removeParentDependencyKey(jobKey, hard, nil, baseKey)
|
||||
if shouldRemoveDeduplicationKey then
|
||||
local deduplicationId = rcall("HGET", jobKey, "deid")
|
||||
removeDeduplicationKeyIfNeededOnRemoval(baseKey, jobId, deduplicationId)
|
||||
end
|
||||
removeJobKeys(jobKey)
|
||||
end
|
||||
local function removeJobs(keys, hard, baseKey, max)
|
||||
for i, key in ipairs(keys) do
|
||||
removeJob(key, hard, baseKey, true --[[remove debounce key]])
|
||||
end
|
||||
return max - #keys
|
||||
end
|
||||
--[[
|
||||
Functions to remove jobs.
|
||||
]]
|
||||
-- Includes
|
||||
--[[
|
||||
Function to filter out jobs to ignore from a table.
|
||||
]]
|
||||
local function filterOutJobsToIgnore(jobs, jobsToIgnore)
|
||||
local filteredJobs = {}
|
||||
for i = 1, #jobs do
|
||||
if not jobsToIgnore[jobs[i]] then
|
||||
table.insert(filteredJobs, jobs[i])
|
||||
end
|
||||
end
|
||||
return filteredJobs
|
||||
end
|
||||
local function getListItems(keyName, max)
|
||||
return rcall('LRANGE', keyName, 0, max - 1)
|
||||
end
|
||||
local function removeListJobs(keyName, hard, baseKey, max, jobsToIgnore)
|
||||
local jobs = getListItems(keyName, max)
|
||||
if jobsToIgnore then
|
||||
jobs = filterOutJobsToIgnore(jobs, jobsToIgnore)
|
||||
end
|
||||
local count = removeJobs(jobs, hard, baseKey, max)
|
||||
rcall("LTRIM", keyName, #jobs, -1)
|
||||
return count
|
||||
end
|
||||
-- Includes
|
||||
--[[
|
||||
Function to loop in batches.
|
||||
Just a bit of warning, some commands as ZREM
|
||||
could receive a maximum of 7000 parameters per call.
|
||||
]]
|
||||
local function batches(n, batchSize)
|
||||
local i = 0
|
||||
return function()
|
||||
local from = i * batchSize + 1
|
||||
i = i + 1
|
||||
if (from <= n) then
|
||||
local to = math.min(from + batchSize - 1, n)
|
||||
return from, to
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
Function to get ZSet items.
|
||||
]]
|
||||
local function getZSetItems(keyName, max)
|
||||
return rcall('ZRANGE', keyName, 0, max - 1)
|
||||
end
|
||||
local function removeZSetJobs(keyName, hard, baseKey, max, jobsToIgnore)
|
||||
local jobs = getZSetItems(keyName, max)
|
||||
if jobsToIgnore then
|
||||
jobs = filterOutJobsToIgnore(jobs, jobsToIgnore)
|
||||
end
|
||||
local count = removeJobs(jobs, hard, baseKey, max)
|
||||
if(#jobs > 0) then
|
||||
for from, to in batches(#jobs, 7000) do
|
||||
rcall("ZREM", keyName, unpack(jobs, from, to))
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
local function removeLockKeys(keys)
|
||||
for i, key in ipairs(keys) do
|
||||
rcall("DEL", baseKey .. key .. ':lock')
|
||||
end
|
||||
end
|
||||
-- 1) Check if paused, if not return with error.
|
||||
if rcall("HEXISTS", KEYS[1], "paused") ~= 1 then
|
||||
return -1 -- Error, NotPaused
|
||||
end
|
||||
-- 2) Check if there are active jobs, if there are and not "force" return error.
|
||||
local activeKey = baseKey .. 'active'
|
||||
local activeJobs = getListItems(activeKey, maxCount)
|
||||
if (#activeJobs > 0) then
|
||||
if(ARGV[2] == "") then
|
||||
return -2 -- Error, ExistActiveJobs
|
||||
end
|
||||
end
|
||||
removeLockKeys(activeJobs)
|
||||
maxCount = removeJobs(activeJobs, true, baseKey, maxCount)
|
||||
rcall("LTRIM", activeKey, #activeJobs, -1)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local delayedKey = baseKey .. 'delayed'
|
||||
maxCount = removeZSetJobs(delayedKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local repeatKey = baseKey .. 'repeat'
|
||||
local repeatJobsIds = getZSetItems(repeatKey, maxCount)
|
||||
for i, key in ipairs(repeatJobsIds) do
|
||||
local jobKey = repeatKey .. ":" .. key
|
||||
rcall("DEL", jobKey)
|
||||
end
|
||||
if(#repeatJobsIds > 0) then
|
||||
for from, to in batches(#repeatJobsIds, 7000) do
|
||||
rcall("ZREM", repeatKey, unpack(repeatJobsIds, from, to))
|
||||
end
|
||||
end
|
||||
maxCount = maxCount - #repeatJobsIds
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local completedKey = baseKey .. 'completed'
|
||||
maxCount = removeZSetJobs(completedKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local waitKey = baseKey .. 'wait'
|
||||
maxCount = removeListJobs(waitKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
-- Backwards compatibility: older versions used a separate "paused" list.
|
||||
local pausedKey = baseKey .. 'paused'
|
||||
maxCount = removeListJobs(pausedKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local prioritizedKey = baseKey .. 'prioritized'
|
||||
maxCount = removeZSetJobs(prioritizedKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
local failedKey = baseKey .. 'failed'
|
||||
maxCount = removeZSetJobs(failedKey, true, baseKey, maxCount)
|
||||
if(maxCount <= 0) then
|
||||
return 1
|
||||
end
|
||||
if(maxCount > 0) then
|
||||
rcall("DEL",
|
||||
baseKey .. 'events',
|
||||
baseKey .. 'delay',
|
||||
baseKey .. 'stalled-check',
|
||||
baseKey .. 'stalled',
|
||||
baseKey .. 'id',
|
||||
baseKey .. 'pc',
|
||||
baseKey .. 'marker',
|
||||
baseKey .. 'meta',
|
||||
baseKey .. 'metrics:completed',
|
||||
baseKey .. 'metrics:completed:data',
|
||||
baseKey .. 'metrics:failed',
|
||||
baseKey .. 'metrics:failed:data')
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
end
|
||||
`;
|
||||
export const obliterate = {
|
||||
name: 'obliterate',
|
||||
content,
|
||||
keys: 2,
|
||||
};
|
||||
Reference in New Issue
Block a user