You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.0 KiB

1 month ago
--[[
Adds a job to the queue by doing the following:
- Increases the job counter if needed.
- Creates a new job key with the job data.
- if delayed:
- computes timestamp.
- adds to delayed zset.
- Emits a global event 'delayed' if the job is delayed.
- if not delayed
- Adds the jobId to the wait/paused list in one of three ways:
- LIFO
- FIFO
- prioritized.
- Adds the job to the "added" list so that workers gets notified.
Input:
KEYS[1] 'wait',
KEYS[2] 'paused'
KEYS[3] 'meta-paused'
KEYS[4] 'id'
KEYS[5] 'delayed'
KEYS[6] 'priority'
ARGV[1] key prefix,
ARGV[2] custom id (will not generate one automatically)
ARGV[3] name
ARGV[4] data (json stringified job data)
ARGV[5] opts (json stringified job opts)
ARGV[6] timestamp
ARGV[7] delay
ARGV[8] delayedTimestamp
ARGV[9] priority
ARGV[10] LIFO
ARGV[11] token
ARGV[12] debounce key
ARGV[13] debounceId
ARGV[14] debounceTtl
]]
local jobId
local jobIdKey
local rcall = redis.call
-- Includes
--- @include "includes/addJobWithPriority"
--- @include "includes/debounceJob"
--- @include "includes/getTargetQueueList"
local jobCounter = rcall("INCR", KEYS[4])
if ARGV[2] == "" then
jobId = jobCounter
jobIdKey = ARGV[1] .. jobId
else
jobId = ARGV[2]
jobIdKey = ARGV[1] .. jobId
if rcall("EXISTS", jobIdKey) == 1 then
rcall("PUBLISH", ARGV[1] .. "duplicated@" .. ARGV[11], jobId)
return jobId .. "" -- convert to string
end
end
local debounceKey = ARGV[12]
local opts = cmsgpack.unpack(ARGV[5])
local debouncedJobId = debounceJob(ARGV[1], ARGV[13], ARGV[14],
jobId, debounceKey, ARGV[11])
if debouncedJobId then
return debouncedJobId
end
local debounceId = ARGV[13]
local optionalValues = {}
if debounceId ~= "" then
table.insert(optionalValues, "deid")
table.insert(optionalValues, debounceId)
end
-- Store the job.
rcall("HMSET", jobIdKey, "name", ARGV[3], "data", ARGV[4], "opts", opts, "timestamp",
ARGV[6], "delay", ARGV[7], "priority", ARGV[9], unpack(optionalValues))
-- Check if job is delayed
local delayedTimestamp = tonumber(ARGV[8])
if(delayedTimestamp ~= 0) then
local timestamp = delayedTimestamp * 0x1000 + bit.band(jobCounter, 0xfff)
rcall("ZADD", KEYS[5], timestamp, jobId)
rcall("PUBLISH", KEYS[5], delayedTimestamp)
else
local target
-- Whe check for the meta-paused key to decide if we are paused or not
-- (since an empty list and !EXISTS are not really the same)
local target, paused = getTargetQueueList(KEYS[3], KEYS[1], KEYS[2])
-- Standard or priority add
local priority = tonumber(ARGV[9])
if priority == 0 then
-- LIFO or FIFO
rcall(ARGV[10], target, jobId)
else
addJobWithPriority(KEYS[6], priority, jobId, target)
end
-- Emit waiting event (wait..ing@token)
rcall("PUBLISH", KEYS[1] .. "ing@" .. ARGV[11], jobId)
end
return jobId .. "" -- convert to string