As much as it is easy to just use a setInterval
to make something happen every x seconds, anything more complicated should be setup as a Cron task. It will also allow you to specify doing something at a specific time of day, even if your Node process were to crash.
My solution for creating this setup easily and in a manageable way is as follows. I have the following script which needs to be run every day at 10.30am which sends a text message via Twilio.
#!/usr/bin/env node var twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN); var done = false; twilio.sendMessage({ to: "[recipient]", from: "[sender]", body: "I was sent at 10.30am today!" }, function(err, response) { done = true; if (err) console.log("Error: " + response.status); else console.log("Sent successfully"); }); setInterval(function() { if (done) { setTimeout(function() { process.exit(); }, 1000); } // Check every second then wait another second before killing }, 1000);
In a real world application based on this, I want to send multiple texts, so the setInterval
block at the end was neccessary because I want the script to wait for Twilio to return all results, then gracefully exit. Does anyone have a suggestion on improving this? It doesn't feel like the most elegant solution. If you were just performing one task, including process.exit()
in it's callback function would be fine.
Making it run at a specific time
Personally I really like the Whenever gem, which is Ruby based, rather than Node, however I find the syntax super easy to use and most importantly pick up again in 18 months time and work out what it is doing.
Get ruby installed and install the whenever gem.
$ gem install whenever
Somewhere on your server run this Whenever task which will create a config folder and a schedule.rb
file which will hold your tasks.
$ wheneverize .
Alongside the config
folder I also like to setup a logs
folder where my task can dump it's output to.
Now that you have Whenever installed customize the schedule.rb
file created by the wheneverize
command. Mine looks like this:
set :output, {:error => 'logs/error.log', :standard => 'logs/cron.log'} every 1.day, :at => '10:30' do command '/usr/local/bin/node /home/deployer/service/current/bin/notify.js' end
The file paths given to set :output
are relative to your user home directory (~
).
My version of Node is installed into /usr/local/bin/node
which you may need to customize. Run which node
to find out where your NodeJS binary is located.
The second argument to Node is the absolute path of my .js script to run.
Whenever has lots of other configuration properties documented in it's README. You could run the same command on a specific day of the week, every hour or at a particular time as we have done here.
Most importantly to finish and actually save your setup run:
whenever -w
If all goes well it should return...
[write] crontab file written
To confirm your crontab file is setup correctly (the file Cron uses for all configuration), run crontab -l
. You should see your JS script command in amongst various other Cron configuration values which Whenever has generated for us.
This is my recommended setup for running a NodeJS script at regular intervals. I hope you find it useful.