Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using concurrent.futures.Future with greenlets/gevent

I have a python library that performs asynchronous network via multicast which may garner replies from other services. It hides the dirty work by returning a Future which will capture a reply. I am integrating this library into an existing gevent application. The call pattern is as simple as:

future = service.broadcast()
# next call blocks the current thread
reply = future.result(some_timeout)

Under the hood, concurrent.futures.Future.result() uses threading.Condition.wait().

With a monkey-patched threading module, this seems fine and safe, and non-blocking with greenlets.

Is there any reason to be worried here or when mixing gevent and concurrent.futures?

like image 622
Nino Walker Avatar asked Oct 01 '22 21:10

Nino Walker


1 Answers

Well, as far as I can tell, futures isn't documented to work on top of threading.Condition, and gevent isn't documented to be able to patch futures safely. So, in theory, someone could write a Python implementation that would break gevent.

But in practice? It's hard to imagine what such an implementation would look like. You obviously need some kind of sync objects to make a Future work. Sure, you could use an Event, Lock, and Rlock instead of a Condition, but that won't cause a problem for gevent. The only way an implementation could plausibly break things would be to go directly to the pthreads/Win32/Java/.NET/whatever sync objects instead of using the wrappers in threading.

How would you deal with that if it happened? Well, futures is implemented in pure Python, and it's pretty simple Python, and there's a fully functional backport that works with 2.5+/3.2+. So, you'd just have to grab that backport and swap out concurrent.futures for futures.

So, if you're doing something wacky like deploying a server that's going to run for 5 years unattended and may have its Python repeatedly upgraded underneath it, maybe I'd install the backport now and use that instead.

Otherwise, I'd just document the assumption (and the workaround in case it's ever broken) in the appropriate place, and then just use the stdlib module.

like image 125
abarnert Avatar answered Oct 05 '22 12:10

abarnert