Search code examples
javascriptnode.jspm2

PM2 delete function problem in Node.js API


I got a very annoying problem with PM2's (version 5.1.0) pm2.delete(process, errback) function. After two days of debugging, trying to find the root of the problem, it starts to look like an issue which is related to the PM2 library itself.

Here a simplified code snippet of what I am doing. I will explain the issue afterwards.

const debug = require("debug")("...");
const pm2 = require("pm2");
const Database = require("./Database");

...

class Backend {
  static cleanup() {
    return new Promise((resolve, reject) => {
      pm2.connect((error) => {
        if (error) {
          debug("...");

          reject();

          return;
        }

        // MongoDB query and async forEach iteration
        Database.getCollection("...").find({
          ...
        })
        .forEach((document) => {
          pm2.delete("service_...", (error, process) => {
            if (!error && process[0].pm2_env.status === "stopped") {
              debug("...");
            } else {
              debug("...");
            }
          });
        })
        .catch(...)
        .then(...);
      }
    });
  }

  ...
}

Now to the problem: my processes do not get terminated and errback of pm2.delete(process, errback) is not executed AT ALL.

  • I printed the error parameter of the connect callback and it is always null, hence a connection to PM2 is established successfully
  • I placed debug text directly at the beginning of the delete callback and it is not printed
  • I wrapped the delete function in a while loop which only stops if the delete callback is executed at least once and the loop runs forever
  • I started a debug session and noticed that PM2's delete function in node_modules/pm2/lib/API.js (line 533) gets called, but for some reason the process does not get terminated and my provided callback function is not executed at all (I went through the commands step by step in debug mode but still can not tell where it fails to execute the callback (it seems to happen in PM2's API.js though))
  • I also noticed that when running the code step by step in debug mode with breakpoints that sometimes my process gets terminated with the API call if I cancle the execution at a certain point in between (however, the callback was still not executed)
  • I use PM2's delete function at another place of my software as well and there it is working like a charm

So for some reason the pm2.delete(process, errback) is not executed correctly and I don't know what to do at this point. Is someone experienced with PM2's source code or had a similar issue at some point? Any advice would be helpful.


Solution

  • It looks like I found the root of the problem:

    At a later point in the promise chain after the forEach call, I use pm2.disconnect();. After further investigation I noticed that it is not perfectly synchronized which means in my case that PM2 gets disconnected before the delete function is completely finished. This gives the described results and the weird debugging behaviour.

    All in all, the API works therefore perfectly fine but one has to pay very close attention to asynchronous code as it can cause really complicated behaviour which is also hard to debug.

    One has to make sure that the delete functions are really finished before pm2.disconnect(); is called.