Search code examples
javascriptnode.jscronagenda

How to wrap Agenda in express apiRoutes in nodejs


I want to schedule a simple task using Agenda with nodejs, however it is not executing when it is wrapped in apiRoutes (express router)

var apiRoutes = express.Router();
app.use('/api', apiRoutes);

apiRoutes.post('/scheduler/submit', function (req, res) {
    agenda.define('test', function () {
         console.log('Test');
    });

    agenda.on('ready', function () {
         agenda.every('*/1 * * * *', 'test');
         agenda.start();
    });
});

but if i place that code outside, it works however. Hmm, any idea?

var apiRoutes = express.Router();
app.use('/api', apiRoutes);

agenda.define('test', function () {
      console.log('Test');
});

agenda.on('ready', function () {
      agenda.every('*/1 * * * *', 'test');
      agenda.start();
});

apiRoutes.post('/scheduler/submit', function (req, res) {
    // Leave blank
});

Solution

  • The problem is the on function. When you call the agenda.on('ready', ...) in your express code you are adding a listen to the agenda emitter's ready array but that signal only occurs when agenda connects to your database when the server initializes. In other words, after agenda connects to your database when the server starts up it will not emit that same signal again which is why the code in your express API isn't executing.

    To fix this, I'd recommend you confirm that agenda has connected to your database successfully and run the process. If not, then add the .on('ready', ...) event listener.

    Sample source:

    var apiRoutes = express.Router();
    app.use('/api', apiRoutes);
    
    // Use this to determine if a conneciton has been established between agenda
    // and the database
    var connectionEstablised = false;
    
    // When the connection is established, set the flag
    agenda.on('ready', function() {
        connectionEstablished = true;
    });
    
    // It's better practice to have this function defined on your agenda object
    // When the server initializes rather than having initializing it only if a POST
    // request occurrs.
    agenda.define('test', function () {
         console.log('Test');
    });
    
    
    
    apiRoutes.post('/scheduler/submit', function (req, res) {
    
        // Only execute this code if you can confirm the connection is established
        if (connectionEstablished) {
            agenda.every('*/1 * * * *', 'test');
            agenda.start();
        }
    });