How to make a task job with PM2?
Asked Answered
A

8

56

I want to make a repeatable job to send mail every 15 minutes taking data from a database table. In node js I can create the job but through PM2 I don't understand where to place the code and how it works.

Airlike answered 28/2, 2017 at 5:55 Comment(2)
I presume you mean a cron job...Vinna
thanks for your reply, i want to send mail automatically after 15 min again and again through pm2 and node js ; what step i have to follow.Airlike
A
-9

thank you for your answer; i do it in this way and just set the email

1.

npm install node-crontab
var crontab = require('node-crontab');

var jobId = crontab.scheduleJob("*/15 * * * *", function(){ 

    //This will call this function every 15 minutes

    console.log("It's been 15 minutes!");

});
Airlike answered 8/3, 2017 at 13:26 Comment(4)
This does not use pm2 as the OP originally asked.Inexpressive
thanks for you reply ; actully i need the corn work and the project manager pm2. so it is very easy to implement by 'node-crontab' .Airlike
@MilanMahata - you know it's cron and not corn right? :) - stackoverflow.com/posts/42501219/revisionsAttu
so does it get re-scheduled on every pm2 start app.js ? or once it is scheduled so it will not be change?Innards
A
126

Use the --cron option:

-c --cron <cron_pattern>

For example:

pm2 start sendMail.js --cron "*/15 * * * *"

Pm2 will now restart the sendMail.js script on the hour, and at 15, 30 and 45 minutes past the hour

Attu answered 1/3, 2017 at 22:36 Comment(9)
And after the script ends, does it stop the process?Virginity
@Virginity that depends on the script you're running - if it ends, then the process will stop, otherwise it will keep running - note that this is nothing to do with pm2, its just nodeAttu
is there a way to put this into a config file of pm2 ?Sophrosyne
The config file has a cron_restart option but that restarts a running application. It doesn't seem to start a terminated script on the cron schedule. I think the correct solution is to use cron-tab as suggested in the accepted answer, along with autorestart: true in pm2Johiah
@Johiah i think that is just a bug - github.com/Unitech/pm2/issues/2487 - i don't think using cron-tab is the "correct solution" - you're probably better off changing your script to not exit as suggested in the issue thread - or submitting a PR to fix the bugAttu
This doesn't work for me. Nothing happens at all. No errors either.Philanthropist
for me, it's weird. if the cron is */5 * * * *, pm2 restarts every 5 seconds... unless i put it to the next position like 0 */5 * * *, and it works as expected. soooo, i doubt the first position means "second" ?!Luminal
@Luminal I experienced the same issue, but my fix is to add --no-autorestart to pm2 start <script> (because my script is a run-once-and-exit-until-started-again type script).Abdominal
@Abdominal I just gave it up, and using crontab instead now. Everything works fine now :)Luminal
S
37

This is what worked for me, I split the cron in a different file which runs in a different process because i want to free up resources after cron has completed execution.

ecosystem.config.js:

module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps: [

    // Main API Hosting
    {
      name: 'API',
      script: 'bin/www',
      env: {
        COMMON_VARIABLE: 'true'
      },
      instances: 1,
      exec_mode: 'cluster',
      watch: false,
      autorestart: true
    },
    {
      name: 'CRON',
      script: "crons/cronjob.js",
      instances: 1,
      exec_mode: 'fork',
      cron_restart: "0,30 * * * *",
      watch: false,
      autorestart: false
    }
  ]
};

The following lines are important in the cron executable

cron_restart: "0,30 * * * *" <- cron expression

autorestart: false <- important because otherwise pm2 will restart the cron after completion immediately

Also make sure your instances is 1 otherwise multiple cron processes will run.

Key caveats:

Whenever you do pm2 restart all, the cron job will run irrespective of the cron expression. If Its critical to run only at specific times, add this additional check in the beginning of the cron file

if (new Date().getHours() !== 0 ) {
  console.log(`Current hours is ${new Date().getHours()}, not running.`)
  process.exit(0);
}
Strachey answered 31/1, 2019 at 7:52 Comment(3)
In this example, what does the cronjob.js contain? Does it import and run the actual script(s)?Inessential
@AntoniaBlair cronjob.js is the actual script itself that you want to run periodically.Strachey
newbedev.com/how-to-make-a-cron-job-with-pm2Dubrovnik
I
20

If you use PM2 ecosystem then in the config file add cron sequence to script param by wrapping it with single quotes. Somehow double quotes didn't work for me.

module.exports = {
  apps : [{
    name        : "Send-mail",
    script      : "./sendMail.js --cron '*/15 * * * *'",
    watch       : true
  }]
}

alternatively (my preference)

module.exports = {
  apps : [{
    name        : "Send-mail",
    script      : "./sendMail.js",
    cron_restart: "*/15 * * * *",
    watch       : true
  }]
}
Instant answered 13/12, 2018 at 17:21 Comment(2)
I believe single quotes worked because "The special parameters * and @ have special meaning when in double quotes" (c) gnu.org/software/bash/manual/html_node/Double-Quotes.htmlSandbag
set autorestart to false since you are already running the script every 15 secondsSanhedrin
C
15

If you execute the following command:

pm2 start handle-cron.js --cron "*/15 * * * *"

PM2 will initiate your cron job, but it will also continuously restart the cron-job after completion. --Infinite Loop

You want to set the instance to 1 and set no-autorestart.

pm2 start handle-cron.js --no-autorestart --instances 1  --cron "0 * * * *"
Chord answered 5/11, 2021 at 4:55 Comment(2)
Helped me, thanks! You should've mentioned the no-restart version first because those who are looking for a cron-like behavior are likely not looking for auto-restarts. but I might be wrong there! :-)Agnail
yeah please edit your answer to not have the wrong code at the topOrnamented
M
4

You can also use the node-schedule module which allows you to define cron style rules. Then, you can run the program normally in pm2, I use this with PM2 for a lot of projects and it has never let me down.

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

var rule = new schedule.RecurrenceRule();
rule.hour = [10]; // 10am
rule.minute = [0]; // 0mins

var job = schedule.scheduleJob(rule, function(){
    console.log("10am every day")
});         

//Rule 2 - 6am every wednesday
var rule2 = new schedule.RecurrenceRule();
rule2.dayOfWeek = 3; // 0 = Sunday
rule2.hour = 6;
rule2.minute = 0;

var job2 = schedule.scheduleJob(rule2, function(){
    console.log("Every Wednesday @ 6am");
});


var rule3 = new schedule.RecurrenceRule();
rule3.minute = [0, 15, 30, 45]; // Specific Minutes

var job3 = schedule.scheduleJob(rule3, function(){
    console.log("Run at specific minutes")
});         

It also supports CRON style rules, but I prefer the above method.

Check out the documentation at https://www.npmjs.com/package/node-schedule

Mim answered 9/2, 2019 at 10:49 Comment(2)
I '+1'ed this answer. Yet, this is too short as an answer to be upvoted. Please, you could be more expressiveMot
This does not use pm2 as the OP originally asked.Strickland
B
0

I usually use pm2 with unix crontab, it allows me to have control over cron using unix itself with ability to use pm2 logs, which I found useful to me.

0 * * * * /usr/bin/pm2 start /var/www/app/cron/index.js --name cron_app

But it's my case, for pm2 cron I would prefer above answers, just never used it as don't like to be dependable on pm2 for cronjobs if can launch it directly via OS crontab.

Bentz answered 3/3, 2023 at 21:18 Comment(0)
B
-2

there are three ways to implement cron through pm2

  1. pm2 command line
  2. pm2 ecosyste.config file
  3. pm2-api

refer this this helped me .

Bravura answered 27/8, 2020 at 7:14 Comment(1)
Yeah, there are many ways to skin a potato. How does it help? and how does that article add value?Cece
A
-9

thank you for your answer; i do it in this way and just set the email

1.

npm install node-crontab
var crontab = require('node-crontab');

var jobId = crontab.scheduleJob("*/15 * * * *", function(){ 

    //This will call this function every 15 minutes

    console.log("It's been 15 minutes!");

});
Airlike answered 8/3, 2017 at 13:26 Comment(4)
This does not use pm2 as the OP originally asked.Inexpressive
thanks for you reply ; actully i need the corn work and the project manager pm2. so it is very easy to implement by 'node-crontab' .Airlike
@MilanMahata - you know it's cron and not corn right? :) - stackoverflow.com/posts/42501219/revisionsAttu
so does it get re-scheduled on every pm2 start app.js ? or once it is scheduled so it will not be change?Innards

© 2022 - 2024 — McMap. All rights reserved.