Live data from Hacker News

Python Asyncio

superfastpython.com

161–170 of 188 posts

Re: Python Asyncio

#161
post #110
post #77

Earlier quoted context omitted.

Specifically distributed would be helped (multiple nodes). Right now the typical paradigm is this really clunky lock-step across nodes waiting for each other (everything is blocking). If your hardware is non-homogenous (both interconnects and accelerators) or your program needs to be run in a pipelined way, you're fighting an extremely uphill battle. Go, JavaScript etc are the usual languages of choice for this type…

I suspect multiprocessing + shared memory could help this. The stdlib has provisions for both, but a coordination layer is needed. That would be closest to true multithreading.

it's not a matter of performance but expressibility.

  const y = await remote_model_a(x) // different machine
  const z = await remote_model_b(y) // different machine
  await z.backward()
is trivially pipelined when run in parallel. With multithreading suddenly the backing C++ library has to be aware of this and figure things out for you

Re: Python Asyncio

#162
post #79

Earlier quoted context omitted.

Asyncio is not ment for CPU Bound Task but for IO Bound Tasks. You should have used multiprocessing. The problem you describe is exactly what asyncio is used for: saturate your bandwidth better. maybe the right aproach would have been a Threadpool? Plus you don't have to refractor the task. Just let it run sync, but you can make it also async

In other languages the async paradigm work for multiple kind of workflows, not just heavily IO bound ones.

But it only does so because you can move out that extra work from the async thread into a thread pool.

In Python there's no benefit in doing this due to the GIL, unless you're using a module which implements its own multithreading (for example in C). Python is not alone with this issue.

In other languages you're basically stepping out of the async paradigm in order to use threading in parallel. You can wait for result of the thread in the async loop without blocking.

I really enjoy using asyncio in Python for things where I have to do a lot of stuff in parallel, like executing remote scripts in a dozen of servers in parallel via AsyncSSH or for low workload servers which query databases.

In any case, what keeps me hooked on Python like a junkie is the `reload(module)` which I invoke via an inotify hook every time a file/module changes:

server.py

server_handler.py

reloader.py

server.py loads reloader.py (which sets up inotify) and that one takes care of reloading server_handler.py whenever it changes. server.py defers all the request/response handling to server_handler.py which can be edited on the fly so that the next request executes the new code. Instant hot reloading.

This also works very nice with asyncio (like aiohttp) and one ends up with very readable code.

If you need performance, then use Java, Rust, Go or C/C++, but for prototyping and tooling I absolutely love this approach with Python.

Re: Python Asyncio

#163

There is very little in everyday Python usage that benefits from Asyncio. Two in webdev, are long running request (Websockets, SSE, long polling), and processing multiple backend IO processes in parallel. However the later is very rare, you may think you have multiple DB request that could use asyncio, but most of the time they are dependent on each other. Almost all of the time a normal multithreaded Python server i…

I don't know what you use Python for every day. Sure for some utility scripts it doesn't matter. I use it to run my ecommerce business, and for a variety of other plumbing, mostly for passing messages around between users, APIs, databases, printers, etc. Async programming is a must for just about everything. I guess the alternative would be thread pools, or process pools, like back in the day; but that has a lot of d…

Same as you, e-commerce store, along with other mostly web projects, quite a bit of real-time and long running requests. I also use Gevent extensively (I prefer it to asyncio).

We use Gevent or Asyncio in a small number of routes that either have long running requests, SSE in our case, or have a very large number of rear facing io requests we can parallelise (a few back office screens and processes).

The complexity that asyncio would add to the the code for the 95% of routs that don't need it would add a lot of unnecessary overhead to development.

My point is, I don't believe it adds any value 95% of the time, but does, sometimes significantly, 5% of the time. I think it's better to only use it where it's really needed and stick to old fashioned, none concurrent, code everywhere else.

Re: Python Asyncio

#164

Earlier quoted context omitted.

The least they could have done is sugared it to something that isn't "def", like "gen" or "defgen"

Unless I'm misunderstanding your comment they do, it's `async def` to denote a coroutine.

It's the buried `yield` in a loop somewhere, magically changing your function into a generator, that can be confusing – it's on the original coder to have the docstring say `"""Generator yielding records from DB."""` or something.

Re: Python Asyncio

#165

Earlier quoted context omitted.

I don't know what you use Python for every day. Sure for some utility scripts it doesn't matter. I use it to run my ecommerce business, and for a variety of other plumbing, mostly for passing messages around between users, APIs, databases, printers, etc. Async programming is a must for just about everything. I guess the alternative would be thread pools, or process pools, like back in the day; but that has a lot of d…

Same as you, e-commerce store, along with other mostly web projects, quite a bit of real-time and long running requests. I also use Gevent extensively (I prefer it to asyncio). We use Gevent or Asyncio in a small number of routes that either have long running requests, SSE in our case, or have a very large number of rear facing io requests we can parallelise (a few back office screens and processes). The complexity t…

Ok, I can agree with that. Gevent doesn't really add any cognitive overhead or complexity at all. Asyncio sure does, and makes the code hard to read too. Long ago I settled on a stack that includes using gevent for anything that listens on a socket, never regretted it.

Re: Python Asyncio

#166

Earlier quoted context omitted.

I have such a feeling of tragedy about Python. I wish it had migrated to BEAM or implemented something similar, instead of growing all this async stuff. Whenever I see anything about Python asyncio, I'm reminded of gar1t's hilarious but NSFW rant about node.js, https://www.youtube.com/watch?v=bzkRVzciAZg . Content warning: lots of swearing, mostly near the end.

That's a blast from the past. Incredible that 10 years ago people thought using a thread per request is a good idea because anything else is too hard.

I'd argue that thread-per-request is even a better idea now, given the massive number of cores and memory in modern servers.

Re: Python Asyncio

#167

Earlier quoted context omitted.

I've experienced something similar using asyncio as well, but I think you're wrong to blame the inherent complexity of concurrent programming. I've used curio as an alternative concurrent programming engine for a med-large project (and many small ones). In comparison to asyncio, it's a joy to use.

What I'm saying if you don't need concurrency, don't trade off simplicity. For REST APIs and websites, probably not needed.

Rest APIs and websites are IO bound. Your python program is there purely coordinating between disk io, database (network) io, calls to other services (io). You can be choreographing thousands of requests concurrently and still barely doing any cpu.

The overhead to do a similar service using threadpools is much higher and the reason asyncio exists.

Re: Python Asyncio

#168

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…

> 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.

Re: Python Asyncio

#169

Earlier quoted context omitted.

I have such a feeling of tragedy about Python. I wish it had migrated to BEAM or implemented something similar, instead of growing all this async stuff. Whenever I see anything about Python asyncio, I'm reminded of gar1t's hilarious but NSFW rant about node.js, https://www.youtube.com/watch?v=bzkRVzciAZg . Content warning: lots of swearing, mostly near the end.

That's a blast from the past. Incredible that 10 years ago people thought using a thread per request is a good idea because anything else is too hard.

BEAM has user level processes and can run millions of them in a not too huge VM.

Re: Python Asyncio

#170
post #66

Earlier quoted context omitted.

that is an absurd exaggeration, or you don't realize all the issues of low level sockets that are abstracted away

To follow up, the contents of read_socket.sh --- #!/bin/bash python3.8 read_one_socket.py $1 --- Use the python socket libraries if you must, but don't use python asynchronously.

id say 90% > of async python usecases are aiohttp , which with a single session, doesn't really have the issues you are describing.
Post reply on HN