Earlier quoted context omitted.
I really think in the end, in another decade or two, the community consensus is going to be that async as it is conceived of today is simply a mistake, full stop. Think about it. Where did it come from in its current incarnation? Node. Why did Node choose it? Did it have a multiplicity of options and carefully choose the best one based on years of experience with each choice? No. Async was "chosen" because it was the…
Async in its current incarnation did not come from node. Eg Haskell had async/await in 1999. https://softwareengineering.stackexchange.com/questions/3774... Node wasn't released until 10 years later.
Local async executors and why they should be the default
131–140 of 327 posts
Re: Local async executors and why they should be the default
#132Just a personal take: after not coding with Rust for several months, I find it more and more difficult to return to an async code I was writing. The whole thing just reads... ugly and inconsistent. It needs too much already-accumulated knowledge. As the article correctly points out, you need a bunch of stuff that are seemingly unrelated (and syntactically speaking you would never guess they belong together). And as o…
Re: Local async executors and why they should be the default
#133Just a personal take: after not coding with Rust for several months, I find it more and more difficult to return to an async code I was writing. The whole thing just reads... ugly and inconsistent. It needs too much already-accumulated knowledge. As the article correctly points out, you need a bunch of stuff that are seemingly unrelated (and syntactically speaking you would never guess they belong together). And as o…
I really think in the end, in another decade or two, the community consensus is going to be that async as it is conceived of today is simply a mistake, full stop. Think about it. Where did it come from in its current incarnation? Node. Why did Node choose it? Did it have a multiplicity of options and carefully choose the best one based on years of experience with each choice? No. Async was "chosen" because it was the…
io_uring for example gives an entirely different model, one with some lovely performance benefits. I'm sure there's a way to make it play well with Rust async and tokio, etc. but they're not really the same model on the surface. And so having bolted async into the language syntax itself, and also adding an explicit requirement on concepts like 'executors' into the language, we've created a legacy problem.
IMHO async in Rust was a mistake. A systems programming language should not have mandated a technique like this, and should have stayed agnostic.
Re: Local async executors and why they should be the default
#134"If you write regular synchronous Rust code, unless you have a really good reason, you don't just start with a thread-pool. You write single-threaded code until you find a place where threads can help you, and then you parallelize it, [..]" I cannot agree more with that. As someone who's done a good deal of Java in my day job, I can tell you a thing or two about spawning threads willy-nilly. At least it is easier to…
It is opt-in. If you're using Tokio then you can specify whether you want to use a single-threaded or multi-threaded runtime. Multi-threaded is "default" in the sense that if you just use `#[tokio::main]` then you get a multi-threaded runtime but you can also just do `#[tokio::main(flavor = "current_thread")]` to get a single threaded executor. More to the point, even using a multi-threaded runtime won't spawn thread…
I have not enough experience about the Rust ecosystem but I hope it will successfully avoid a similar fate.
Re: Local async executors and why they should be the default
#135Wait, async is multithreaded by default in Rust? For me the whole point of using async in JavaScript or Python (originally with Twisted's @inlineCallbacks) was to get concurrency without threads. Imagine writing code for a computer game bot: move left, wait for enemy, attack enemy... You normally can't write it like this because it would block the rest of your program. Async allows you to go from "program sequential"…
So for example, the tokio executor could run single threaded or on a thread pool. However, tokio::task::spawn takes a future as an argument that may be evaluated on a different thread, so any caller of this API and the designers of the library behind it need to guarantee the argument is thread safe.
That constraint is reflected through the type system by constraining the argument type of tokio::task::spawn(fut: Future + impl Send + 'static) which means "fut is a type that implements Future with the output of type T and is Send (safe to send to a different thread) and does not have any lifetimes that outlive the 'static lifetime (contains no references to non-static data)".
Re: Local async executors and why they should be the default
#136Earlier quoted context omitted.
I really think in the end, in another decade or two, the community consensus is going to be that async as it is conceived of today is simply a mistake, full stop. Think about it. Where did it come from in its current incarnation? Node. Why did Node choose it? Did it have a multiplicity of options and carefully choose the best one based on years of experience with each choice? No. Async was "chosen" because it was the…
We wrote asynchronous driven network code for decades without syntactic sugar for it, and it was fine. That 5% performance gain can be had without it. Async syntax is a mistake. Not just because of the mess it makes across the program tree, but also because it brings with it a specific notion of how to do asynchronous I/O. io_uring for example gives an entirely different model, one with some lovely performance benefi…
Rust doesn't mandate anything. It's unipinionated when it comes to concurrency; use whatever approach that you think is best. Async/await is just one option among many.
Re: Local async executors and why they should be the default
#137Just a personal take: after not coding with Rust for several months, I find it more and more difficult to return to an async code I was writing. The whole thing just reads... ugly and inconsistent. It needs too much already-accumulated knowledge. As the article correctly points out, you need a bunch of stuff that are seemingly unrelated (and syntactically speaking you would never guess they belong together). And as o…
Continuations and the way Erlang handles this have far less mental overhead and help keeping the model and the mental representation of that model in sync. Differences between the two is where bugs will hide.
The web isn't asynchronous it's synchronous in almost every aspect the whole reason all this async stuff became so popular (at least, as far as I understand it) is because there is a mismatch between your typical process and having a large number of clients dangling off it. The solution - in my opinion - is to solve this by making it easier to have more processes, which can then block while waiting for the other side, not by adding layer upon layer of complexity to try to stick to the wrong set of tools or to shoehorn a larger problem into a box too small to contain it.
It essentially gets you all of the complexity of interrupt driven code for very little gain and without the memory protection that a process driven approach would have. This whole async solution is to offer an alternative to Node, (even if it originated elsewhere that's clearly the competition for Rust) and should have stayed there, it's an ugly wart on Rust and a distraction to boot.
Re: Local async executors and why they should be the default
#138Earlier quoted context omitted.
If you want golang in Rust just use channels and tasks? Or threads? I don't find async Rust difficult at all, I'm having a hard time really empathizing with this to the extent of needing breaking changes. To me, async from a lang perspective is virtually done - in 2024 I suspect all of the various impl Trait and async Trait stuff will be done and at that point I don't see anything left.
I think this blog post by tomaka gives a good summary of the current issues with async rust. Certainly much more comprehensive than what you can write in a hacker news post: https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d... It highlights some of the same problems: - “Just spawn a new task” - The Send trait isn’t what it means anymore
I wonder why I haven't hit these issues despite writing web services in Rust for years.
Re: Local async executors and why they should be the default
#139Earlier quoted context omitted.
We wrote asynchronous driven network code for decades without syntactic sugar for it, and it was fine. That 5% performance gain can be had without it. Async syntax is a mistake. Not just because of the mess it makes across the program tree, but also because it brings with it a specific notion of how to do asynchronous I/O. io_uring for example gives an entirely different model, one with some lovely performance benefi…
> A systems programming language should not have mandated a technique like this Rust doesn't mandate anything. It's unipinionated when it comes to concurrency; use whatever approach that you think is best. Async/await is just one option among many.
Re: Local async executors and why they should be the default
#140Earlier quoted context omitted.
I think this blog post by tomaka gives a good summary of the current issues with async rust. Certainly much more comprehensive than what you can write in a hacker news post: https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d... It highlights some of the same problems: - “Just spawn a new task” - The Send trait isn’t what it means anymore
I guess I just don't run into these issues. Maybe because I write my code to be effectively single threaded already. I almost never actually need a channel, mutex, etc, except in very specific and scoped areas. I wonder why I haven't hit these issues despite writing web services in Rust for years.
The typical context for stuff like async/await is code that should be running in a separate process so it can block but doesn't. Then it gets ugly fast.