抛出异常:Node.js与Gevent

Throwing exceptions: Node.js vs Gevent

本文关键字:Gevent js Node 抛出异常      更新时间:2024-06-02

昨天有人在聚会上告诉我,如果回调在Node.js中抛出异常,将导致整个进程崩溃。但是,如果一个绿绿灯在Gevent中抛出一个未捕获的异常,它只会使绿绿灯崩溃。

我没有Gevent的经验,我想知道这是不是真的。

Node.js应用程序在未捕获异常时崩溃吗?对参见例如。,http://shapeshed.com/uncaught-exceptions-in-node/

Gevent greenlet中未捕获的异常是否只会降低有问题的greenlet?对参见例如。,http://www.gevent.org/gevent.html尤其是CCD_ 1"如果greenlet以错误结束,则保留函数引发的异常实例",从而使该异常实例可用于进程的其余部分,而该进程不会崩溃。

这里有一个exmaple代码,它显示当一个greenlet抛出一个未捕获的excpetion时,整个过程不会崩溃。代码在这里,输出如下:

Traceback (most recent call last):  
File "/usr/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run  
  result = self._run(*self.args, **self.kwargs)  
File "test_exception_greenlet.py", line 31, in _fail  
  raise Exception('you fail')  
Exception: you fail  
<Greenlet at 0x8b5cc5c: <bound method TestgException._fail of <__main__.TestgException object at 0x8bd4a0c>>> failed with Exception  
win ready? True    
fail ready? True  
win successful()? True  
fail successful()? False  
exception: Exception('you fail',)  

使用gevent实现并发任务时,需要生成一些coroutines,即greenlets,然后主线程切换到一个名为hub的特殊greenlet,然后在greenlets之间进行循环。工作流程如下:

主线程->一个greenlet->枢纽greenlet->一个greenlet->枢纽greenlet->a greenlet->…->一些greenlet->主线程->。。。(可能再次进入循环)

从这里,你应该知道一个greenlet是如何在内部运行的。greenlet是Greenlet的一个实例。当一个greenlet运行时,它会调用它的run()方法。以下是Greenlet.exception0类中run()的源代码:

def run(self):
    try:
        if self._start_event is None:
            self._start_event = _dummy_event
        else:
            self._start_event.stop()
        try:
            result = self._run(*self.args, **self.kwargs)
        except:
            self._report_error(sys.exc_info())
            return
        self._report_result(result)
    finally:
        self.__dict__.pop('_run', None)
        self.__dict__.pop('args', None)
        self.__dict__.pop('kwargs', None)

这里的_run()方法是一个绑定,其中包含一个要作为greenlet运行的任务。从这里可以看到,如果发生异常,它将被_report_error()方法捕获并报告。通过阅读前者调用的_report_error()_report_result()的源代码,您知道它捕获了异常,只有绿绿灯熄灭,而不是整个过程。当一个greenlet引发一个未捕获的异常时,它将死亡,hub greenlet将不再调度它。

如果您对Greenlet的实现感兴趣,以下是源代码