2022-12-16
Sometimes I wonder if we, the engineers always look for the most complicated way of achieving the simplest goals. Or do we set the goals that aren't attainable with plain tools? Either way, we end up creating complexity where there shouldn't be one and then spend months, years, decades unrolling this mess into something manageable.
And ultimately failing.
I see a large number of engineers flock to async as the way of life. Why is that? My hypothesis is async is The Way To Go™ in JavaScript world and being the world's most popular programming language it's also the first language for a majority of new programmers.
Is async any good?
I am struggling to come up with solid arguments for either yes or no. Async just is. What is definitely not good is how we collectively use async. More often than not async code I look at will have the beautiful pattern of:
for thing in things:
await io_op(thing)
Littering code with await
s is not going to magically speed up the
code nor is it going to make it more scalable.
Another common pattern I've observed is:
def async foo(bar):
# Bunch of sync calls
async with async_resource() as r:
await r.io_op(bar)
# Sync calls
# Sync calls
return None
This code does not have to be async and yet it is. It's also more likely than ever the only bit of code leveraging async but every caller is now forced to become async. Async is quite contagious that way.
Armin Ronacher wrote on the topic of async https://lucumr.pocoo.org/2020/1/1/async-pressure/ and he focused extensively on how async can hide a certain type of network load. I'd argue that async gives a large number of developers an illusion of well-performing code. An illusion that reinforces their desire to use async for usecases where async doesn't give any benefits while definitely introducing additional overhead in code maintenance.
It's equally
We have somehow decided that https://werkzeug.palletsprojects.com/en/2.2.x/debug/ is
https://github.com/alex-oleshkevich/starception
Top-level async code support is patchy. IPython implements a
workaround which works until it doesn't. It's definitely better than
nothing but I sure as hell miss having the ability to run %%timeit
on code I'm trying to figure out.
IPython and async are friends. Python built-in interpreter... less so. And even tho IPython are friends, they have some disagreements to work on https://ipython.readthedocs.io/en/stable/interactive/autoawait.html#effects-on-magics
The tooling essential for REPL-driven development is still lagging behind. But of course, as most developers (66% as of 2021) use highly-integrated tooling https://lp.jetbrains.com/python-developers-survey-2021/#DevelopmentTools it matters less. Or does it? Do we want to penalize people who have found effective workflow in tools other than VS Code or PyCharm? Are we happy monopolize the field of editors for Python?
I believe async is of limited use in your run-of-the mill CRUD app. It's only useful in very specific set of IO-bound scenarios which are rarely if ever present in web apps or data science work. And if you end up in such a situation where a performance of your code matters so much you have to for broke (async) then you might as well consider alternative approaches (Go, Rust, C#, Kotlin).
So if performance is not the selling point of async then what is? I'm still struggling to come to terms that in an industry so hell-bent on calling itself engineers there's so little thought about proving whether this path is the right one.
https://www.techempower.com/benchmarks/#section=data-r21&l=zijzen-6bj&test=query https://werkzeug.palletsprojects.com/en/2.2.x/debug/#werkzeug.debug.DebuggedApplication