Gevent ThreadPool exception swallowed

Before gevent-1.1.0, the gevent ThreadPool does not raise exception with AsyncResult after a DeviceProxy.read_attribute command:

from tango import DevFailed
from tango.gevent import DeviceProxy

try:
    ds = DeviceProxy("sys/tg_test/1")
    value = ds.read_attribute("throw_exception") # here value is None
except DevFailed;
    print("Not accessible")

The exception is swallowed by the ThreadPool and it is not propagated to the AsyncResult.


In tango_gevent.py the def spawn(fn, *args, **kwargs):method has been deployed as a fix to wrap the ThreadPool.spawn result and re-raise exception raised by the called method. This fix is not used by the DeviceProxy.read_attribute command because the executor returned by the tango.green.get_executor method is direclty the gevent's ThreadPool.

  • tango.green.get_executor returns is tango.tango_gevent.get_global_executor
  • tango.tango_gevent.get_global_executor is tango.tango_gevent.get_global_threadpool
  • tango.tango_gevent.get_global_threadpool returns gevent.get_hub().threadpool

This bug can be fixed by using gevent-1.1.0 or more because the ThreadPool now raises any exception raised by the called function ( gevent change log. )

For older version of gevent, we should still wrap the ThreadPool spawn method, and use it as default executor.

(PR incoming)