无法在适当的时间致电处置在域上 [英] Unable to call dispose on domain at appropriate time

查看:56
本文介绍了无法在适当的时间致电处置在域上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在domain模块上遇到问题.目前,我正在尝试捕获请求中引发的所有未捕获的错误.使用express中间件和域.在调用next并继续其正确的路由之前,所有请求均通过此函数进行路由.

I'm having an issue with the domain module. Currently, I'm trying to catch any uncaught errors that are thrown in a request. Using an express middleware and domains. All requests are routed through this function before calling next and moving on to it's proper route.

app.use (req, res, next) ->
    domain = createDomain()
    domain.on "error", (err) ->
        res.send(500)
        domain.dispose()

    domain.enter()
    next()

问题是,如果从未抛出错误,我该如何处置该域?

The problem is, how do I dispose of the domain if an error is never thrown?

我可以将域和事件悬挂在中间件之外,这样就不必进行处理,但随后我将无法访问需要发送500个中间件的args.

I could hoist the domain and event outside the middlewear so I don't ever have to dispose, but then I won't have access to middlewear args that I need to send a 500.

有人对我的处理方式有更好的解决方案吗?我花了太多时间试图找出一种方法(以及许多骇人听闻的方法)来解决这个问题.谢谢.

Does anyone have a better solution to how I am handling this? I've spent way too much time trying to figure out a way (and many hacky ways) to handle this. Thanks.

推荐答案

如果没有发生错误,则无需调用domain.dispose(). domain.dispose()的目的是清除跳出堆栈中间后处于不确定状态的所有资源,并抑制由于不良状态而可能发生的后续错误. domain.enter()的反向调用就是domain.exit().

You do not need to call domain.dispose() if no errors occurred. The purpose of domain.dispose() is to clean up any resources that were left in an indeterminate state after jumping out out the middle of the stack, and to squelch subsequent errors that would occur due to the bad state. The inverse call of domain.enter() is simply domain.exit().

也就是说,浏览域代码时,您似乎不想以这种方式使用domain.enter/exit.每个domain.enter/exit对应于域模块代码中共享阵列的堆栈推入/弹出.因此,例如,如果第二个请求在第一个请求完成之前进入,然后第一个请求在第二个请求退出之前退出,则在第一个域处理程序中调用exit将弹出第二个请求的域.进入和退出似乎不应该在异步事物之间分割.

That said, browsing through the code for domains, it looks like you don't want to use domain.enter/exit this way. Each domain.enter/exit corresponds to a stack push/pop of a shared array in the domain module code. So, for example, if a second request comes in before the first one has completed, and then the first one exits before the second one does, calling exit in the first domains handler will pop the domain for the second request. It seems quite likely that enter and exit should not be split across asynchronous things.

您是否尝试过仅使用domain.run(next)?这似乎对我有用.它基本上会为您输入域,然后调用您提供给它的回调,然后在回调返回后立即退出该域.您在域中时创建的任何计时器或事件发射器也将自己与该域关联.然后,事件发射器在调用事件处理程序时也会使用类似的enter-call-exit模式.在代码中似乎不是跟踪事件处理程序的域,而是跟踪域的事件处理程序.

Have you tried simply using domain.run(next)? That seems to do the trick for me. It basically enters the domain for you and then calls the callback you give to it, and then immediately exits the domain after the callback returns. Any timers or event emitters created while you are in the domain will associate themselves with that domain, as well. Event emitters then also use a similar enter-call-exit pattern when calling event handlers. It appears in the code that it is not domains that track event handlers, but rather event handlers that track domains.

简而言之,不要尝试将enter与dispose配对,也不要尝试在异步边界上使用enter/exit.使用运行/绑定/添加/删除.

In short, don't try to pair an enter with a dispose, and don't try to use enter/exit across asynchronous boundaries. Use run/bind/add/remove.

这篇关于无法在适当的时间致电处置在域上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆