Jack Robson
Jack Robson

Reputation: 2302

Scheduling Tasks in Node.js Using Timers instead of Scheduled Cron Jobs

This is my objective:

5 minutes after the last document update, I want to execute a one-time task

So this is what the flow of actions will look like:

  1. User updates document - timer is started and counts down from 5 minutes
  2. If user updates the same document again and the previous timer (identified by the document._id) is running still, reset that timer back to 5 minutes and repeat countdown
  3. When timer has elapsed - the one time task is executed

I have not done something like this before and I am at a loss at where to begin.

I can hook into document changes easily using methods available in Mongoose (i.e. on save, do func to setup or reset timer)

However, I cannot figure out the way to:

I've investigated Cron jobs but they seem to tasks that schedule at the same time everyday.

I need a timer that delays a task, but also the ability to reset that timer, and add extra data to the timer.

Any hints appreciated.

Upvotes: 2

Views: 3752

Answers (3)

Albert Alberto
Albert Alberto

Reputation: 952

I had the same puzzle but I ended settling on the javascript native functions.

function intervalFunc() {
  //inside this function you can request to get the date and time then decide what to do and how to do it
  autogens.serverAutoGenerate();//my function to autogenerate bills
}

setInterval(intervalFunc, 1000);//repeat task after one seconds

Adding the code at the index file or entry file of your node js application will make the function repeatedly execute. You can opt to change the frequency depending on your needs. If you wanted to run the cronjob three times a day, get the number of seconds in 24 hours then divide by 3. If you wanted to run the job on a specific hour, by using the new Date(), you can check to determine if it is the right hour to execute your event or not.

Upvotes: 0

Jack Robson
Jack Robson

Reputation: 2302

This is the solution I managed to complete up with.

First of all, it's worth noting that my original assumptions are correct:

Cron jobs are great for repetitive, tasks that are scheduled at the same time everyday. However, for tasks that are created on the fly, and have a countdown element, then cron jobs isn't the right tool.

However, enter node-schedule (https://www.npmjs.com/package/node-schedule)

Node Schedule is a flexible cron-like and not-cron-like job scheduler for Node.js. It allows you to schedule jobs (arbitrary functions) for execution at specific dates, with optional recurrence rules. It only uses a single timer at any given time (rather than reevaluating upcoming jobs every second/minute).

The use of timers is really what these, on-the-fly tasks need.

So my solution looks like this:

var schedule = require('node-schedule'),
email_scheduler = {};

email_scheduler["H1e5nE2GW"] = schedule.scheduleJob(Date.now() + 10000, function(){
  console.log('its been a total of 10 seconds since initalization / reset.');
});

var second_attempt = schedule.scheduleJob(Date.now() + 5000, function(){
  console.log("5 seconds elapsed from start, time to reset original scheduled job");

  email_scheduler["H1e5nE2GW"].cancel();

  email_scheduler["H1e5nE2GW"] = schedule.scheduleJob(Date.now() + 10000, function(){
    console.log('its been a total of 10 since last one seconds.');
  });

  schedule.scheduleJob(Date.now() + 5000, function(){
    console.log("it's been another 5 seconds since reset");

  });
});

My thinking (though not yet tested) is that I can create a singleton-like instance for the email_scheduler object by creating a node module. Like such:

// node_modules/email-scheduler/index.js

module.exports = {};

This way, I can access the scheduleJobs and reset the timers in every file of the node application.

Upvotes: 1

Yuvraj
Yuvraj

Reputation: 66

You can use events for that. call a event with some parameter and before your task add sleep and exec your task. But add sleep or settimeout is not a good idea in nodejs.

Upvotes: 0

Related Questions