Node.js API 中的 PM2 删除功能问题
PM2 delete function problem in Node.js API
我在使用 PM2(5.1.0 版)pm2.delete(process, errback)
功能时遇到了一个非常烦人的问题。经过两天的调试,试图找到问题的根源,它开始看起来像是与PM2库本身有关的问题。
这是我正在做的事情的简化代码片段。稍后我会解释这个问题。
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(...);
}
});
}
...
}
现在问题来了:我的进程没有终止,pm2.delete(process, errback)
的 errback
根本没有执行。
- 我打印了连接回调的错误参数,它总是
null
,因此成功建立了与 PM2 的连接
- 我将调试文本直接放在删除回调的开头,但没有打印出来
- 我将 delete 函数包装在一个 while 循环中,只有在 delete 回调至少执行一次并且循环永远运行时该循环才会停止
- 我启动了一个调试会话并注意到
node_modules/pm2/lib/API.js
(第 533 行)中的 PM2 删除函数被调用,但由于某种原因该进程没有终止并且我提供的回调函数根本没有执行(我在调试模式下一步一步地完成了命令,但仍然无法判断它在哪里执行回调失败(它似乎发生在 PM2 的 API.js 中))
- 我还注意到,当 运行 在带有断点的调试模式下逐步执行代码时,如果我在中间的某个点取消执行,有时我的进程会因 API 调用而终止(但是回调还是没有执行)
- 我也在我的软件的另一个地方使用了 PM2 的删除功能,它在那里工作得很好
所以由于某种原因,pm2.delete(process, errback)
没有正确执行,此时我不知道该怎么做。是否有人对 PM2 的源代码有经验或在某个时候遇到过类似的问题?任何建议都会有所帮助。
看来我找到了问题的根源:
在 forEach 调用之后的承诺链中,我使用了 pm2.disconnect();
。经过进一步调查,我注意到它没有完全同步,这意味着在我的情况下,PM2 在删除功能完全完成之前断开连接。这给出了描述的结果和奇怪的调试行为。
总而言之,API 工作得非常好,但必须非常密切地注意异步代码,因为它会导致非常复杂的行为,也很难调试。
必须确保在调用 pm2.disconnect();
之前删除函数确实完成。
我在使用 PM2(5.1.0 版)pm2.delete(process, errback)
功能时遇到了一个非常烦人的问题。经过两天的调试,试图找到问题的根源,它开始看起来像是与PM2库本身有关的问题。
这是我正在做的事情的简化代码片段。稍后我会解释这个问题。
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(...);
}
});
}
...
}
现在问题来了:我的进程没有终止,pm2.delete(process, errback)
的 errback
根本没有执行。
- 我打印了连接回调的错误参数,它总是
null
,因此成功建立了与 PM2 的连接 - 我将调试文本直接放在删除回调的开头,但没有打印出来
- 我将 delete 函数包装在一个 while 循环中,只有在 delete 回调至少执行一次并且循环永远运行时该循环才会停止
- 我启动了一个调试会话并注意到
node_modules/pm2/lib/API.js
(第 533 行)中的 PM2 删除函数被调用,但由于某种原因该进程没有终止并且我提供的回调函数根本没有执行(我在调试模式下一步一步地完成了命令,但仍然无法判断它在哪里执行回调失败(它似乎发生在 PM2 的 API.js 中)) - 我还注意到,当 运行 在带有断点的调试模式下逐步执行代码时,如果我在中间的某个点取消执行,有时我的进程会因 API 调用而终止(但是回调还是没有执行)
- 我也在我的软件的另一个地方使用了 PM2 的删除功能,它在那里工作得很好
所以由于某种原因,pm2.delete(process, errback)
没有正确执行,此时我不知道该怎么做。是否有人对 PM2 的源代码有经验或在某个时候遇到过类似的问题?任何建议都会有所帮助。
看来我找到了问题的根源:
在 forEach 调用之后的承诺链中,我使用了 pm2.disconnect();
。经过进一步调查,我注意到它没有完全同步,这意味着在我的情况下,PM2 在删除功能完全完成之前断开连接。这给出了描述的结果和奇怪的调试行为。
总而言之,API 工作得非常好,但必须非常密切地注意异步代码,因为它会导致非常复杂的行为,也很难调试。
必须确保在调用 pm2.disconnect();
之前删除函数确实完成。