meteor-job-collection
meteor-job-collection copied to clipboard
Cannot pause/cancel jobs, by using jc.pauseJobs/jc.cancelJobs
I have a few long running joobs which are doing stuff in loop for a given amount of tries on server, and i want to try and stop them from client.
So the jobs created like so :
//server
workers = Job.processJobs('jobQueue', 'dowork',
function(job,cb){
for(var limit = 0; limit < max; limit++) {
//..do work
Meteor._sleepForMs(job.data.delay);
}
}
);
//client
var job = new Job( jobQueue, 'dowork', data ).priority( 'normal' ).retry(
{
retries: 0
}
).repeat({ repeats : 0, wait: 0 }).delay( 0 ).save();
Then i want to stop it from client, for that i wrote a method based on your suggestion, to manually update jobQueue status parameter:
//server
Meteor.methods({
clearJobs: function(){
var ids = jobQueue.find({}, {fields: {_id: 1}}).map(function(d) { return d._id; });
try {
jobQueue.update({ status: { $in: jobQueue.jobStatusPausable }},{multi:true});
jobQueue.pauseJobs(ids);
jobQueue.cancelJobs(ids);
}
catch(ex){
console.log(ex);
}
finally {
jobQueue.removeJobs(fields);
}
}
});
//client
'click #clearJobs': function(e,instance){
Meteor.call('clearJobs',function(err,result){
console.log("done");
});
}
But i always get error jobPause failed
. If i remove jobQueue.pauseJobs(ids);
and only do cancel, nothing happens and jobs keep running i see output in console. At least they get removed in the end, but what i did wrong to cancel/stop them?
Hi, running jobs cannot be paused in the way you are assuming. If you look at the definition of jc.jobStatusPausable
you will find:
jc.jobStatusPausable = [ 'ready', 'waiting' ];
Note, that 'running'
is not one of those options. The reason? There is no way for the server to reach into a worker and cause it to reversibly "pause".
You can irreversibly "cancel" a running job, however:
jc.jobStatusCancellable = [ 'running', 'ready', 'waiting', 'paused' ];
But actually stopping the running worker code requires that the worker is actively "checking in" with the server by periodically calling job.progress()
or job.log()
and checking the return value (if false
the job is no longer running and the worker should clean-up what it is doing and call its cb()
).
I want to add that you could certainly define workloads that can be "partially completed" by using persistent state pointed to by the job data
. Cancelling such a worker would allow it to save its progress, and restarting such a cancelled job could cause it to resume from where the previous run left-off, updating its job.progress()
with the server accordingly. But there are many way to accomplish this and while job-collection creates a flexible framework making this possible, it does not implement it for you.