抛出异常:Node.js vs Gevent

时间:2013-12-10 20:10:33

标签: javascript python node.js exception-handling gevent

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

我没有Gevent的经验,我想知道这是否属实。

2 个答案:

答案 0 :(得分:1)

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

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,然后主线程应切换到名为greenlet > hub 然后循环发生在greenlets之间。工作流程如下:

  

主线程 - &gt;一个greenlet - &gt; hub greenlet - &gt;绿色 - &gt; hub greenlet - &gt;绿色 - &gt; ... - &gt;一些greenlet - &gt;主线程 - &gt; ......(可能再次进入循环)

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

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死了而不是整个过程。当greenlet引发未捕获的异常时,它会死亡,而hub greenlet将不再安排它。

如果您对Greenlet的实施感兴趣,请参阅source code

答案 1 :(得分:1)

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

Gevent greenlets中未被捕获的异常只会降低有问题的greenlet吗?是。例如,参见http://www.gevent.org/gevent.html,特别是Greenlet.exception “如果greenlet已经完成了错误,则保存函数引发的异常实例”,从而使异常实例可用于进程的其余部分,但不会崩溃。