Async IO Support

Async IO Support

I’m no fan of Async IO, but it’s increasingly becoming unavoidable day to day. However I am a fan of Nameko, and I think it provides great abstractions to various RPC interfaces.

I know this has obviously been floated in the past, and people have been a little unsure how to integrate Async IO without fundamentally changing the design of Nameko. I’ve seen some other libraries that for a long time have been ‘sync only’ like SQLAlchemy use some Greenlet magic to integrate with the Async IO event loop.

Here’s a little example that was used as the basis for integrating Async IO into SQLAlchemy.

1 Like

If you’re interested in this, I’d be happy to put the time in to build a POC like this:

from nameko.rpc import rpc

class GreetingService:
    name = "greeting_service"

    @rpc
    async def hello(self, name):
        return "Hello, {}!".format(name)

2 Likes

Hi @sonthonaxrk,

This is cool, thanks for writing. The Python concurrency landscape has changed a lot since Nameko was conceived, and, frankly, being based on Eventlet is problematic. I would love to see more compatibility with the new status quo.

I’m hopeful that some concurrency primitives could be packaged up in a way that supports multiple frameworks, like Eventlet/Gevent, Asyncio or even plain threads.

Nameko is reasonably clear about its concurrency requirements:

  • Workers are single-threaded and should not need to consider concurrency
  • Entrypoints should expect to spawn multiple worker threads concurrently
  • Each worker thread will call get_dependency on each DependencyProvider

I’d love to see a POC.

1 Like

Very interesting! I’ve considered implementing a MVP nameko-like service with aiormq or aio-pika, but never really had the spare time to do so. To me personally, eventlet feels a little bit like a dead end now in light of async being a core language feature of Python.

Furthermore, several libraries I’d like to use with nameko are now embracing asyncio as well. One - as @sonthonaxrk mentioned in the first post - is SQLAlchemy which adds some async support in 1.4. (We’re using SQLAlchemy with nameko/eventlet right now, but that works due to some special treatment of psycopg2 in eventlet).
The other is graphene, which should release v3 soon. It appears that they switched from promise-based APIs to built-in async/await. As long as one uses only the sync APIs of graphene, eventlet monkey patching is sufficient. But what if we wanted to use subscriptions over websockets? I don’t think we could reconcile async/await-based subscriptions with nameko.web.websocket at this moment.

With that said, I’m eager to see any attempt to bring nameko closer to supporting asyncio or multiple concurrency APIs. I’m willing to help, although my asyncio experience is limited to only using async libraries, not developing new ones.

Edit: I’ve dug out a PR that adds gevent compatibility which may be inspiring for future work (when it gets merged and released is another question).

2 Likes

Async/await support would really be helpful. I’m still quite new in the async business, but have been using Nameko for quite some time.
Maybe an integration with fast-api is possible, or anyio for that matter.