Stop/abort/terminate 需要(已加载)模块

Stop/abort/terminate required (loaded) module

是否有可能 stop/abort/terminate 一个 required/loaded 模块?

我在这里 () 找到了一些东西:

var name = require.resolve('moduleName');
delete require.cache[name];

但这不是 stop/abort 一个 运行 计时器或类似的东西。 它只是继续执行脚本的操作。

我需要这个的原因是,我想实现一个插件系统,您可以在其中启动和停止插件。

“启动”很简单,只需加载 require(...) 代码即可。 但是停止插件正在做的一切的最好方法是什么?

我考虑过虚拟机,但在节点中无法中止虚拟机执行。 接下来我想到的是“工作线程”。他们提供了一个 .terminate 方法来满足我的需要。 (但现在我必须处理进程间通信,这对于保持一切同步非常复杂)

如果有人能给我一个就太好了hint/tip。

Nodejs 不提供任何功能来执行您想要的操作,因此您将不得不手动执行大量操作。正如您所发现的,删除模块缓存的模块只会影响您尝试再次加载代码时发生的情况,它根本不会影响已经加载的代码。

如果您要将 plug-ins 保持在同一个进程中,那么您可以在 plug-ins 中实现一个所需的方法,称为“关机”之类的方法,其中 plug-in手动关闭自身(停止计时器、注销事件处理程序等)。如果实施得当,这应该会完全断开它与 nodejs 程序中的任何内容的连接。如果您随后从 require 缓存中删除该模块,则可以在其位置加载一个新模块。这样做的一个缺点是 nodejs 永远不会卸载原始代码——它只是留在内存中。如果您不访问原始模块句柄,则该代码永远不会再次使用,但它不会被 nodejs 释放或 GC。

一个更健壮的系统是将每个 plug-in 放在它们自己的 child-process 或工作线程中,并通过 [=35= 之间的 built-in 进程间通信与它们通信] 和 child 本质上只是消息传递的过程。只要您不必在 parent 和 child/worker 之间发送大量数据或拥有超高带宽数据,那么消息传递就非常简单易用并且运行良好。

如果使用单独的 child 进程,您可以随时终止 child 进程并且 OS 将回收该进程使用的所有资源(对于一个工作线程)。这有其自身的缺点,因为它可能会使用更多的内存,因为 nodejs 中的全新 nodejs 进程或 workerThread 比仅将单个模块加载到现有的 nodejs 进程中更重。

运行 它在 child 进程中的优点是您的主进程受到更多保护,免受 plug-in 中的错误代码(意外或恶意)的影响,因为它们是不同的进程和 plug-in 不能直接干扰 parent 进程。但是,不要在这里自欺欺人,除非你 运行 它在沙盒 VM 中,plug-in 仍然会对系统造成一些破坏,因为它可以访问系统上的许多资源(磁盘、网络) , 其他外设等...).