2

I am implementing a booking system, and I need to record the concept of the time between the job being accepted and the job starting, and then the duration of the job. I need to move from 'State A' to 'State B' when the start time of the job is reached, and then from 'State B' to 'State C' once the end time of the job has been reached.

I know I could implement this using a queue system like Bull or Bee-Queue, but it seems wrong, as I only need to change the 'State' of my job, not perform any background processing.

How can I simply say "At 3pm, change this Task to 'State B', and at 5pm, change this Task to 'State C'".

Could I poll my DB every minute? Is this the 'correct' approach?

simon-p-r
  • 3,623
  • 2
  • 20
  • 35

3 Answers3

2

How about using node-cron module? You can use node-cron to schedule jobs based on time, frequency etc. see the official link for more examples https://www.npmjs.com/package/node-cron

I pasted one for reference

var cron = require('node-cron');

cron.schedule('* * * * *', function(){
console.log('running a task every minute');
});
manishg
  • 9,520
  • 1
  • 16
  • 19
  • This seems to be used for recurring tasks. I need a task to occur at a particular time interval, but it seems [Crone](https://github.com/crrobinson14/crone) solves this. –  Feb 01 '17 at 11:20
  • It uses cron syntax so you can set it to do at a particular time interval as well. – manishg Feb 01 '17 at 12:29
  • Just once? Can I say "I want this to run on the 23rd June 2016 at 4:05:13pm" –  Feb 01 '17 at 12:30
  • Standard cron will allow you to do 23rd June at 4:05:13pm but not the year so it will repeat every year. There are few suggestions available at http://stackoverflow.com/questions/5473780/how-to-setup-cron-to-run-a-file-just-once-at-a-specific-time-in-future which can be tried. – manishg Feb 01 '17 at 12:36
  • You can always check the year once the task runs and stop if the job if you want to (https://github.com/kelektiv/node-cron/blob/master/README.md) – manishg Feb 01 '17 at 12:53
  • probably better to have the task destroy the schedule when its done - https://github.com/merencia/node-cron#destroy. – Robbie Feb 03 '17 at 20:48
  • I think i'd be more concerned about what happens when you restart your app. E.g. a user creates a booking, your app creates a schedule to run a job at a set time in the future. Then you deploy a new version of the app - requiring a restart - so your schedule is now lost. If you scale your app servers dynamically under heavy load, you'll have a similar problem. If you add 1 new server, and it creates any schedules, then you scale down, removing that server, all the schedules running on it will be lost. – Robbie Feb 03 '17 at 20:49
  • I guess then the schedule has to be stored in db. – manishg Feb 03 '17 at 20:51
  • you could, but i think it would get complicated fast. If you have multiple app servers running. You're going to store the jobs in the db, and then have the servers check on startup if they need to create a schedule. This means you need to keep track of which jobs are scheduled and which aren't to avoid duplicating them. How do you even know if a server that was scheduling a job suddenly dies, or is reset? – Robbie Feb 03 '17 at 20:58
  • Is it possible to run at a specific date without time ? – kd12345 Nov 07 '22 at 13:15
0

An approach that doesn't involve scheduling would be to have the value of your state property calculated at request time.

Instead of updating the value of state at exactly 3pm, you check the current time when someone requests the booking resource. If it's >3pm and <5pm return the state as 'State B'. If its >5pm, return state as 'State C'.

Robbie
  • 18,750
  • 4
  • 41
  • 45
  • I did have that thought. How does this change if I need to do something else i.e. Send an email? Is a queue required then? –  Jan 31 '17 at 20:05
  • i'd probably offload the work to a scheduling system. chronos perhaps - https://mesos.github.io/chronos/ - you can talk HTTP to its api to configure scheduled jobs that do what ever you need – Robbie Jan 31 '17 at 20:14
  • you can create a script that knows how to send emails. Then when a customer creates a booking in your system, your api makes a HTTP request to the scheduling system telling it to run your email script at a set time – Robbie Jan 31 '17 at 21:30
  • Hi, is it possible to run a task based on a specific date? eg. on the 31st of December 2022 – kd12345 Nov 14 '22 at 10:24
-1

You can use setTimeout(function, timeout) to schedule task at certain period of time.

var now = new Date(); //creates date object at current time
var date = new Date(...); //create first state-changing time

//Execute task after (date - now) milliseconds
setTimeout(function(){
    //execute tasks
}, date - now);

Now you can do setTimeout() inside setTimeout() with the help of loops to complete your task!