Someone at a meetup yesterday told me that if a callback throws an exception in Node.js, it will crash the entire process. But if a greenlet throws an uncaught exception in Gevent, it only crashes the greenlet.
I don't have experience with Gevent, and am wondering if that is true.
Here is an exmaple code that shows that when a greenlet throws an uncaught excpetion, the whole process won't be crashed. The code is here and the output is as following:
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',)
When using gevent
to implemenet concurrency tasks, you should generate some coroutines
, namely greenlets
, and then the main thread should switch to a special greenlet
named hub and then the loop happens among greenlets
. The workflow is like this:
main thread -> one greenlet -> hub greenlet -> a greenlet -> hub greenlet -> a greenlet -> ... -> some greenlet -> main thread -> ... (maybe enters the loop again)
From here, you should know how a greenlet runs internally. A greenlet is an instance of Greenlet
. When a greenlet runs, it invokes its run()
method. Here is the source code of run()
in Greenlet
class:
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)
The _run()
method here is a binding with a task you want to run as a greenlet. From here you could see that if an exception happens, it will be caught and reported by _report_error()
method. By reading the source code of _report_error()
and _report_result()
which is invoked by the former, you know that it catches the exception and just the greenlet dies but not the whole process. When a greenlet raises an uncaught exception, it dies and the hub
greenlet won't schedule it any more.
If you're insterested in the implementation of Greenlet
, here is the source code
Do Node.js apps crash upon uncaught exception? Yes. See, eg, http://shapeshed.com/uncaught-exceptions-in-node/
Do uncaught exceptions in Gevent greenlets only bring down the greenlet in question? Yes. See, eg, http://www.gevent.org/gevent.html and in particular Greenlet.exception
which "holds the exception instance raised by the function if the greenlet has finished with an error," thus making the exception instance available to the rest of the process, which did not crash.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.