【问题标题】:Stop/abort/terminate required (loaded) module停止/中止/终止所需(加载)模块
【发布时间】:2021-09-21 02:53:23
【问题描述】:

是否有可能的方法来停止/中止/终止所需/加载的模块?

我在这里 (https://stackoverflow.com/a/6677355/5781499) 找到了一些东西:

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

但这不会停止/中止正在运行的计时器或类似的东西。 它只是继续做脚本所做的事情。

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

“启动”很简单,只需加载require(...) 代码即可。 但是停止插件正在执行的所有操作的最佳方法是什么?

虽然我有一个关于 VM 的信息,但是在节点中没有办法中止任何一个 vm 执行。 我想到的下一件事是“工作线程”。他们提供了一个.terminate 方法来满足我的需要。 (但现在我必须处理进程间通信,保持一切同步非常复杂)

如果有人能给我一个提示/提示,那就太棒了。

【问题讨论】:

    标签: node.js plugins abort worker-thread


    【解决方案1】:

    Nodejs 没有提供任何功能来做你想做的事,所以你必须手动做很多事情。正如您所发现的,删除模块缓存的模块只会影响您尝试再次加载代码时发生的情况,它根本不会影响已经加载的代码。

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

    更健壮的系统是将每个插件放在自己的子进程或工作线程中,并通过父子进程之间的内置进程间通信与它们进行通信,这本质上只是消息传递。只要您不必在父子/worker 之间发送大量数据或拥有超高带宽数据,那么消息传递就非常易于使用并且运行良好。

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

    在子进程中运行它的好处是,您的主进程可以更好地防止插件中的错误代码(意外或恶意),因为它们是不同的进程并且插件不能直接混淆父进程。但是,不要在这里自欺欺人,除非你在沙盒虚拟机中运行它,否则插件仍然会对系统造成一些破坏,因为它可以访问系统上的许多资源(磁盘、网络、其他外围设备等)。 ..)。

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 2012-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多