pm2 icon indicating copy to clipboard operation
pm2 copied to clipboard

[fix] cron should gracefully reload process

Open titanism opened this issue 11 months ago • 3 comments

What's going wrong?

Disclosure: We haven't seen this issue on GitHub Issues nor Pull Requests tabs here on GitHub at https://github.com/Unitech/pm2/issues/new, therefore we are filing this is as a new issue. There are related discussion threads on StackOverflow however, see the references below.

Issue: The issue is that the cron-restart option does not call reload, and therefore it does a hard-restart on an existing running application (as opposed to a graceful reload via pm2 reload). The underlying reason for this is the code below which calls God.restartProcessId as opposed to God.reloadProcessId (restart vs reload).

https://github.com/Unitech/pm2/blob/311c53298448fc4575fc689c4943692a664373ad/lib/Worker.js#L39

https://github.com/Unitech/pm2/blob/311c53298448fc4575fc689c4943692a664373ad/lib/God/ActionMethods.js#L387

https://github.com/Unitech/pm2/blob/311c53298448fc4575fc689c4943692a664373ad/lib/God/Reload.js#L218

References:

How could we fix this issue?

Current Workaround: The current workaround is to add the following line to crontab on your server and then modify the paths appropriately. Here are the three steps required to achieve this:

  1. ssh your-server
  2. Run which node and which pm2 to get the full paths to the executables for node and pm2. In the example below we are using n, but your paths may differ slightly, e.g. it may be /usr/local/bin/node and /usr/local/bin/pm2.
  3. Edit crontab using crontab -e and in the editor (e.g. vim) add the following line to the bottom, then save via :wq:
    0 */4 * * * /home/deploy/n/bin/node /home/deploy/n/bin/pm2 reload all > /dev/null 2>&1
    

How to Fix the Issue: To fix this issue, we'd have to open a pull request that modifies the logic as such:

  God.registerCron = function(pm2_env) {
    if (!pm2_env ||
        pm2_env.pm_id === undefined ||
        !pm2_env.cron_restart ||
        pm2_env.cron_restart == '0' ||
        God.CronJobs.has(God.getCronID(pm2_env.pm_id)))
      return;

    var pm_id = pm2_env.pm_id
    console.log('[PM2][WORKER] Registering a cron job on:', pm_id);

    var job = Cron(pm2_env.cron_restart, function() {
+      God.softReloadProcessId({id: pm_id}, function(err, data) {
-      God.restartProcessId({id: pm_id}, function(err, data) {
        if (err)
          console.error(err.stack || err);
        return;
      });
    });

    God.CronJobs.set(God.getCronID(pm_id), job);
  }

titanism avatar Jul 10 '23 18:07 titanism