我们正在构建一个允许用户提供自己的“模块”来运行的应用程序。我们正在寻找一种需要模块的方法,然后在需要时删除或杀死模块。我们看了一些似乎在讨论此主题的教程,但似乎无法使模块完全终止。我们通过使用模块内部的计时器对此进行了探索,即使在删除模块引用之后,也可以观察到计时器仍在运行。
https://repl.it/repls/QuerulousSorrowfulQuery
index.js
// Load module
let Mod = require('./mod.js');
// Call the module function (which starts a setInterval)
Mod();
// Delete the module after 3 seconds
setTimeout(function () {
Mod = null;
delete Mod;
console.log('Deleted!')
}, 3000);
./mod.js
function Mod() {
setInterval(function () {
console.log('Mod log');
}, 1000);
}
module.exports = Mod;
预期输出
Mod log
Mod log
Deleted!
实际输出
Mod log
Mod log
Deleted!
Mod log
...
(continues to log 'Mod log' indefinitely)
也许我们考虑得太多了,也许这些模块不会成为内存消耗,但是我们所装载的模块将具有非常繁重的工作负载,并且能够随意停止它们显得很重要。
无法杀死模块并停止或关闭它正在使用的任何资源。那不是node.js的功能。这样的模块可能具有计时器,打开文件,打开套接字,正在运行的服务器等。此外,node.js不提供“卸载”曾经加载的代码的方法。
您可以从模块缓存中删除一个模块,但这不会影响现有的,已经加载的代码或其资源。
我知道的唯一简单的方法是将用户的模块加载到作为子进程加载的单独的node.js应用中,然后您可以退出该进程或终止该进程,然后操作系统将回收其正在使用的任何资源并从内存中卸载所有内容。该子处理方案还具有以下优势:用户代码与您的主服务器代码更加隔离。如果需要,您甚至可以通过在VM中运行此其他进程来进一步隔离它。