-
Notifications
You must be signed in to change notification settings - Fork 796
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
Rerunning jobs after server shutdown #74
Comments
I guess every time i start my node server, i should look through the jobs collection and schedule them back? |
Do you have definitions for |
@rschmukler yes i do. the job name comes from the data passed from socket.io message "createJob" |
@MurWade can you try updating to |
@rschmukler awsome thanks. |
Did it work? |
@rschmukler sorry didn't mention that i will try it. Haven't tried it yet. |
Fairly certain this is related to #70, as I was seeing this exact same issue happen to me. That being said, I think I'm going to add a test to ensure .every() jobs don't get reran when the server restarts. |
I am using 0.6.16 and am having this issue as well. Jobs pending in the database when the script is loaded to not ever get scheduled EDIT: I tried resetting up the jobs manually, but this seems to duplicate the jobs as well. For now I guess the workarount would be to remove the jobs first, then reschedule directly after |
Ya i tried it with the latest still the same issue. |
I have this problem too. It looks like My understanding is that job definitions are not being stored in the database. I originally thought that the fix simply required On a related note: It's clear that Agenda doesn't write or read job definitions from the database, but what about actual jobs? Obviously |
@RebootJeff , thats idea i had. didnt really look at the code, but i am guessing the job _definition is the function that executes every time the job runs. how can this be saved in the database anyway. |
@MurWade - Yea pretty much. The To answer your question: saving definitions would look something like... Agenda.prototype.define = function(name, options, processor) {
if(!processor) {
processor = options;
options = {};
}
this._definitions[name] = {
fn: processor,
concurrency: options.concurrency || this._defaultConcurrency,
priority: options.priority || 0,
lockLifetime: options.lockLifetime || this._defaultLockLifetime,
running: 0
};
// NEW CODE STARTS HERE
saveDefinition(name, this._definitions[name]);
};
function saveDefinition(definitionName, definition) {
var props = {
type: 'definition', // this is questionable, but we need some way to show that this database item is a definition rather than another job
name: definitionName,
data: definition
};
// Add new definition to database or update if it already exists in database
this._db.update({ name: name }, props, { upsert: true });
// My mongo code might be missing a callback?
} Sorry if my code looks crappy. I'm used to mongoose + promises rather than mongo + callbacks. |
Not sure this will work as definition contains the function and "scope" for each job. You could serialize and perist the function in mongo, but i'm not sure how you deserialize back the full state. Looks like wiping and recreating jobs on server startup may be the only option. |
Are you guys dynamically generating job definitions? If not, why do they need to be stored in the database? If so, what's the use case? If possible, jobs should be stored using variables, and those variables used for dynamic jobs. This helps for a few reasons:
So, for example, instead of: agenda.define('send-registration-' + user.id(), function(job, done) {
emailService.send('Thanks for registering ' + user.name() , user.email(), done);
})
agenda.once('send-registration-' + user.id()) You should do: agenda.define('send registration email', function(job, done) {
var data = job.data;
emailService.send('Thanks for registering ' + data.name, data.email, done);
})
// Elsewhere in code
agenda.once('send registration email', { name: user.name(), email: user.email() }); If I am missing the boat on this one, please let me know the use case so I can see why you're dynamically generating job definitions. @wired8 @RebootJeff @MurWade @droppedonjapan |
My jobs aren't dynamic, they follow your recommended example. The issue I believe comes down to repopulating agenda._definitions[name].fn after server restart. This is the function which performs the job. I did manage to serialize _definitions including job functions in Mongo, but this won't work because you also need to set the dependencies (requires) and state of all job functions. The example above would require a reference to emailService. For now I simply purge all jobs and reload them on server restart, this works well enough. |
@wired8 if they aren't dynamic, why cant you have something that looks like the following: var agenda = new Agenda(mongoStuff);
agenda.define('example job 1', function() { /* do stuff */ });
agenda.define('example job 2', function() { /* do stuff */ });
agenda.define('example job 3', function() { /* do stuff */ });
agenda.define('example job 4', function() { /* do stuff */ });
agenda.start(); |
That exactly what I have. If you restart node, your job queue will always be 0, because the _definitions object will be empty. Should we be recreating all job definitions on app start by calling agenda.define for each job? |
So the way I always envisioned it is that you define the jobs that you want the worker to process (above) before starting it, and then it starts processing jobs that it has definitions for. This lets you do things like specify limited job queues. For example, consider the following project structure and files for a worker. project:
Sample job processor (eg. var email = require('some-email-lib'),
User = require('../models/user-model.js');
module.exports = function(agenda) {
agenda.define('registration email', function(job, done) {
User.get(job.data.userId, function(err, user) {
if(err) return done(err);
email(user.email(), 'Thanks for registering', 'Thanks for registering ' + user.name(), done);
});
});
agenda.define('reset password', function(job, done) {
// etc etc
})
// More email related jobs
} worker.js var Agenda = require('agenda');
var jobTypes = process.env.JOB_TYPES.split(',');
var agenda = new Agenda(connectionOpts);
jobTypes.forEach(function(type) {
require('./lib/jobs/' + type)(agenda);
})
agenda.start(); Now you can do the following to spin up a worker that processes jobs of a given type:
Hope this helps, let me know. |
That looks like a better example Ryan. You should add that to the readme, and a donate button.. ;-) |
Haha, thanks. I'll definitely add it to the documentation. I'll consider the donate button as well :P |
I am facing the same issue but in my case i am using dynamic job creation. here is my use case. i am billing businesses and each business has a different billing date.For each business, the billing should repeat after every x month(which is also different for each business). at the moment this is how am creating and stating jobs
jobName will be pass from the calling code. and this is how i start the job
However when the server restart the job does not start again. Hope someone can help. thanks |
@Osmandiyaka were you able to figure it out? I am stuck with the same issue and I am creating jobs dynamically. |
@raunaqkapoor can you try this
|
@raunaqkapoor did you find any work around on this? |
@DevanshB10 can't recall for the life of me! Was 4 years back and I don't have access to that repo any longer. Sorry! Maybe try this |
Hey guys, Love the library. Thank you.
I just had a question about agenda and how it saves jobs.
does saving a job mean that onces the node server is shutdown and restarted, it will continue to process the jobs saved in the database? if not, the what is the alternate solution?
I have tried saving jobs, but after restarting my node script, it does not run my old jobs. Here is my script
The text was updated successfully, but these errors were encountered: