2013-12-10 39 views
0

昨天聚會上的某個人告訴我,如果回調在Node.js中引發異常,將會導致整個過程崩潰。但是,如果greenlet在Gevent中引發未捕獲的異常,它只會使greenlet崩潰。拋出異常:Node.js vs Gevent

我沒有Gevent的經驗,我在想這是否屬實。

回答

1

待辦事項的Node.js應用程序崩潰?是。請參閱,例如,http://shapeshed.com/uncaught-exceptions-in-node/

在Gevent greenlets中未捕獲的異常只會導致有問題的greenlet?是。例如,參見http://www.gevent.org/gevent.html,特別是Greenlet.exception,其中 「如果greenlet完成了一個錯誤,則包含該函數引發的異常實例」,從而使得該異常實例可用於未發生崩潰的進程的其餘部分。

1

這是一個exmaple代碼,它顯示了當greenlet引發一個未捕獲的消息時,整個過程不會崩潰。該代碼是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到implemenet併發任務,你應該產生一些coroutines,即greenlets,然後主線程應該切換到一個特殊的greenlet名爲樞紐然後循環發生在greenlets之間。工作流程如下:

主線程 - >一個greenlet - > hub greenlet - >一個greenlet - > hub greenlet - >一個greenlet - > ... - >一些greenlet - >主線程 - >。 ..(也許再次進入循環)

從這裏,你應該知道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引發一個未捕獲的異常時,它會消失,greenlet不會再計劃它。

如果你在Greenlet實施insterested,這裏是在未捕獲的異常的source code

+0

你忘了添加答案;) –

+0

@TommasoBarbugli,對不起,我不知道你的意思。我的答案是第一句,另一個是解釋。 – flyer