node.jscronpm2node-cron

PM2: Node.js App with Cron Jobs on Droplet - Reloading Server and Duplicate Cron Runs


I have a Node.js application running on node v16.15.0 within a Digital Ocean droplet. The app employs cron jobs using the node-cron v3.0.1 package to handle significant processes.

Problem: whenever I deploy new code, I find it necessary to reload (gracefully restart) the Node.js server using the command pm2 reload my-app. Unfortunately, this action results in the termination of my active cron processes. Is there a way to perform a server reload without interrupting the running cron jobs?

In my attempts to improve performance, I have increased the number of clusters. However, this adjustment has led to a problem where cron jobs are duplicated and run multiple times. And for that I implemented

process.env.NODE_APP_INSTANCE === 0

for initialising crons.

Thank you for any insights and guidance you can provide.

I attempted the suggested approach of using pm2 graceful restart as outlined earlier, but unfortunately, it did not yield the expected results. The issue with the cron jobs being affected by the server restart still persists. Any further assistance would be greatly appreciated.


Solution

  • I resolved this issue by changing a few things in my code as follows:

    process.on("SIGTERM", () => gracefull());
    process.on("SIGINT", () => gracefull());
    
    /**
     * Handle graceful shutdown
     */
    function gracefull() {
      console.log(
        "Received shutdown signal. Waiting for running jobs to complete..."
      );
    
      /* Set the flag to indicate shutdown */
      myCron.isShuttingDown = true; // This will indicate that now do not execute new tasks in the cron
    
      /* If no jobs are running, exit immediately */
      if (myCron.running) {
        myCron.on("cronDone", () => {
          console.log("The Cron complete signal received");
          process.exit(0);
        });
      } else {
        console.log("No running jobs. Exiting gracefully.");
        process.exit(0);
      }
    }