Hacker News new | ask | show | jobs
by leveraction 1317 days ago
I have used asyncio through aiohttp, and I have been pretty happy with it, but I also started with it from the beginning, so that probably made things a little easier.

My setup is a bunch of microservices that each run an aiohttp web server based api for calls from the browser where communications between services are done async using rabbitmq and a hand rolled pub/sub setup. Almost all calls are non-blocking, except for calls to Neo4j (sadly, they block, but Neo4j is fast, so its not really a problem.)

With an async api I like the fact that I can make very fast https replies to the browser while queing the resulting long running job and then responding back to the Vue based SPA client over a web socket connection. This gives the interface a really snappy feel.

But Complex? Oh yes.

But the upside is that it is also a very flexible architecture, and I like the code isolation that you get with microservices. Nevertheless, more than once I have thought about whether I would choose it all again knowing what I know now. Maybe a monolithic flask app would have been a lot easier if less sexy. But where's the fun in that?

3 comments

> With an async api I like the fact that I can make very fast https replies to the browser while queing the resulting long running job and then responding back to the Vue based SPA client over a web socket connection. This gives the interface a really snappy feel.

How does this compare to doing the same with eg. Django Channels (or other ASGI-aware frameworks)?

I have yet to find a use case compelling enough to dive into async in Python (doesn't help that I also work in JS and Go so I just turn to them for in cases where I could maybe use asyncio). This is not to say it's useless, just that I'm still searching for a problem this is the best solution for.

I have never used Django, so I cannot say but if Channels handles the websocket connection back to the client, then I assume you could send back a quick 200 notification as the http response to the user and then send the real results later over the socket. I think these would be equivalent.

I have also never used Go, but I am comfortable saying that Python async is much easier to user than JS async. I find JS to be as frustrating as it is unavoidable.

Using aiohttp as on api is not bad at all. Once you have the event loop up and running, its a lot like writing sync code. Someone else made a comment about the fact that Python has too many ways to do async because everything keeps evolving so fast. I this this is true. The first time I ever looked at async on Python it was so nasty I basically gave up and reconsided Flask but came back around later because I so despised the idea of blocking by server that I was compelled to give it another go. The next time around was a lot easier because the libraries were so much improved.

I think a lot of people think that async Python is harder than it is (now).

> Maybe a monolithic flask app would have been a lot easier if less sexy. But where's the fun in that? Not to sound snarky, but the fun would be in being able to solve business problems without fighting against a complex system. Microservices can definitely make sense but if you need them and know you need them. If it's just for fun and it's not a hobby, and you're being paid to maintain someone else's system then it's definitely worth going with a simpler system.
I share your sentiment and have been using aiohttp for five years and pretty happy with it. My current project is a web service with blocking SQL server backend, so I tend to do loop.run_in_executor for every DB.execute statement. But now I’m considering just running a set of light aio streams sub processes with a simple bespoke protocol that takes a SQL statement and returns the result json encoded to move away from threads.