Throwing exceptions: Node.js vs Gevent-Collection of common programming errors
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
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