【问题标题】:What exactly does domain.dispose() do in nodejs? Are there any hooks?domain.dispose() 在 nodejs 中究竟做了什么?有没有钩子?
【发布时间】:2013-04-01 18:40:28
【问题描述】:

阅读http://nodejs.org/api/domain.html 的文档会有点模糊:“尽最大努力尝试清理与域关联的所有 IO”。它提到计时器已关闭,这不完全是 IO。很高兴知道 domain.dispose 所做的事情的完整列表。有人有这个清单吗?

另外,是否有任何方法可以连接到该功能 - 即允许在运行 domain.dispose() 时调用一些自定义清理代码?

【问题讨论】:

    标签: javascript node.js error-handling


    【解决方案1】:

    dispose 函数调用 exit 和 dispose 函数,删除所有侦听器,删除所有错误处理程序,并尝试杀死域的所有成员。该函数检查域是否有父域,如果有,则将其从域中删除。然后将域设置为垃圾收集,并标记为已处置。

    来自节点文档:

    一旦域被释放,dispose 事件就会发出。

    我会更深入地讨论这个主题,但 Node 源代码已经很好地注释了。

    您所说的计时器将在这里,域的成员正在被迭代。

    this.members.forEach(function(m) {
      // if it's a timeout or interval, cancel it.
      clearTimeout(m);
    });
    

    来自节点source

    Domain.prototype.dispose = function() {
      if (this._disposed) return;
    
      // if we're the active domain, then get out now.
      this.exit();
    
      this.emit('dispose');
    
      // remove error handlers.
      this.removeAllListeners();
      this.on('error', function() {});
    
      // try to kill all the members.
      // XXX There should be more consistent ways
      // to shut down things!
      this.members.forEach(function(m) {
        // if it's a timeout or interval, cancel it.
        clearTimeout(m);
    
        // drop all event listeners.
        if (m instanceof EventEmitter) {
          m.removeAllListeners();
          // swallow errors
          m.on('error', function() {});
        }
    
        // Be careful!
        // By definition, we're likely in error-ridden territory here,
        // so it's quite possible that calling some of these methods
        // might cause additional exceptions to be thrown.
        endMethods.forEach(function(method) {
          if (typeof m[method] === 'function') {
            try {
              m[method]();
            } catch (er) {}
          }
        });
    
      });
    
      // remove from parent domain, if there is one.
      if (this.domain) this.domain.remove(this);
    
      // kill the references so that they can be properly gc'ed.
      this.members.length = 0;
    
      // finally, mark this domain as 'no longer relevant'
      // so that it can't be entered or activated.
      this._disposed = true;
    };
    

    【讨论】:

    • 所以看起来“dispose”事件可能是我想知道的钩子。似乎很奇怪,他们在使用 clearTimeout 之前不检查成员是否超时。他们从运行的 endMethods 中隐藏未捕获的异常似乎有点不对劲。成为“域成员”的事物是什么?有没有办法让自定义对象成为域成员?消息来源不清楚。
    • 是的,这些方法看起来不太干净,虽然我不是一个非常有经验的编码器,所以我不太了解。我确实有一个问题 - 你在说什么类型的自定义对象?成员是 EventEmitter 的任何类型,因为域专门用于将多个 I/O 操作作为一个组来处理。
    • 我所说的自定义对象真的是你能想到的任何东西。一个例子是一些用于处理某些专有协议上的 TCP 通信的模块。如果您希望在通过 dispose() 死亡之前发送错误,协议可能会期望一些特定的消息。如果能够确保您的自定义内容与核心 IO 功能等一样干净利落,那就太好了。
    • 对象如EventEmitters..?我并没有真正理解你想要做的事情,你是否试图让它的所有实例都在域中启动?
    • 将成员添加到域时,它会添加到对象中。然后,当您调用dispose() 时,循环只会遍历该对象,而不是更深。因此,我的回答是否定的,它们不会被处理掉,如果你要向域中添加东西,它们应该是 EventEmitters。
    猜你喜欢
    • 2011-06-18
    • 2012-07-23
    • 2016-09-10
    • 2023-03-15
    • 2012-10-17
    • 2021-06-04
    • 1970-01-01
    • 2018-07-30
    • 2019-10-06
    相关资源
    最近更新 更多