-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow custom job ids to be specified in the job options #335
Changes from all commits
0ef22f8
7c5940c
2e9940b
02f4009
e744956
1b765e5
77f6b77
6c8e29d
ceb827f
7369515
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,7 +65,10 @@ var scripts = { | |
return result === 1; | ||
}); | ||
}, | ||
addJob: function(client, toKey, lifo, job){ | ||
addJob: function(client, toKey, job, opts){ | ||
opts = opts || {}; | ||
opts.lifo = !!(opts.lifo); | ||
|
||
var jobArgs = _.flatten(_.toPairs(job)); | ||
|
||
var keys = _.map(['wait', 'paused', 'meta-paused', 'jobs', 'id', 'delayed'], function(name){ | ||
|
@@ -74,28 +77,32 @@ var scripts = { | |
var baseKey = toKey(''); | ||
|
||
var argvs = _.map(jobArgs, function(arg, index){ | ||
return ', ARGV['+(index+2)+']'; | ||
return ', ARGV['+(index+3)+']'; | ||
}) | ||
|
||
var script = [ | ||
'local jobId = redis.call("INCR", KEYS[5])', | ||
'redis.call("HMSET", ARGV[1] .. jobId' + argvs.join('') + ')', | ||
'local jobCounter = redis.call("INCR", KEYS[5])', | ||
'local jobId', | ||
'if ARGV[2] == "" then jobId = jobCounter else jobId = ARGV[2] end', | ||
'local jobIdKey = ARGV[1] .. jobId', | ||
'if redis.call("EXISTS", jobIdKey) == 1 then return jobId end', | ||
'redis.call("HMSET", jobIdKey' + argvs.join('') + ')', | ||
]; | ||
|
||
var scriptName; | ||
|
||
var delayTimestamp = job.timestamp + job.delay; | ||
if(job.delay && delayTimestamp > Date.now()){ | ||
script.push.apply(script, [ | ||
' local timestamp = tonumber(ARGV[' + (argvs.length + 2) + ']) * 0x1000 + bit.band(jobId, 0xfff)', | ||
' local timestamp = tonumber(ARGV[' + (argvs.length + 3) + ']) * 0x1000 + bit.band(jobCounter, 0xfff)', | ||
' redis.call("ZADD", KEYS[6], timestamp, jobId)', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch since we use the jobCounter for the delay logic. |
||
' redis.call("PUBLISH", KEYS[6], (timestamp / 0x1000))', | ||
' return jobId', | ||
]); | ||
|
||
scriptName = 'addJob:delayed'; | ||
}else{ | ||
var push = (lifo ? 'R' : 'L') + 'PUSH'; | ||
var push = (opts.lifo ? 'R' : 'L') + 'PUSH'; | ||
// | ||
// 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) | ||
|
@@ -106,7 +113,7 @@ var scripts = { | |
' redis.call("' + push + '", KEYS[2], jobId)', | ||
'end', | ||
'redis.call("PUBLISH", KEYS[4], jobId)', | ||
'return jobId' | ||
'return jobId .. ""' | ||
]); | ||
|
||
scriptName = 'addJob'+push; | ||
|
@@ -121,6 +128,7 @@ var scripts = { | |
|
||
args.push.apply(args, keys); | ||
args.push(baseKey); | ||
args.push(opts.customJobId || ''); | ||
args.push.apply(args, jobArgs); | ||
args.push(delayTimestamp); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,28 @@ describe('Job', function(){ | |
expect(storedJob.opts.testOpt).to.be('enabled'); | ||
}); | ||
}); | ||
|
||
it('should use the custom jobId if one is provided', function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test case suggestion: Create a job with a customId and test if it can be processed, in the |
||
var customJobId = 'customjob'; | ||
return Job.create(queue, data, { jobId: customJobId }).then(function(createdJob){ | ||
expect(createdJob.jobId).to.be.equal(customJobId); | ||
}); | ||
}); | ||
|
||
it('should process jobs with custom jobIds', function(done) { | ||
var customJobId = 'customjob'; | ||
queue.process(function () { | ||
return Promise.resolve(); | ||
}); | ||
|
||
queue.add({ foo: 'bar' }, { jobId: customJobId }); | ||
|
||
queue.on('completed', function(job) { | ||
if (job.opts.jobId == customJobId) { | ||
done(); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
describe('.remove', function () { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since lifo is optional and customId also, I think it is more convenient to put it in an opts argument, and also move it to the last argument in the list:
function(client, toKey, job, opts)