Live data from Hacker News

Local async executors and why they should be the default

maciej.codes

121–130 of 327 posts

Re: Local async executors and why they should be the default

#121

Wait, 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"…

> Wait, async is multithreaded by default in Rust?

No, whether or not async is multithreaded depends on whether or not your executor is multithreaded. Rust doesn't ship an executor by default, you need to bring your own. Tokio, the most popular general-purpose executor, is multithreaded by default, and can be configured to be single-threaded.

Re: Local async executors and why they should be the default

#122
post #47
post #44

Earlier quoted context omitted.

Having written a lot of async and sync rust, and having both components interact with one another, calling async stuff from a sync context isn't even that ugly these days. But maybe it's stockholm syndrome.

It's OK but not great. Ideally library authors should provide a sync facade so people don't have to deal with this, like reqwest does.

Ideal for library users but not for library authors...

Re: Local async executors and why they should be the default

#123

Earlier quoted context omitted.

> now there is a MVP syntax and everything has just slowed down a lot. Sadly this is spot on. Seems like after async was delivered there was only one big push from tokio 0.1 to 0.2 to 1.0 and that was it, the ecosystem and/or language maintainers seem to have lost interest in making it better to read and use.

The fun part is over. At least that is how a rust maintainer described it to me. When I asked why doing the unfun part (documentation, maintenance, etc.) isn't a condition for allowing people to do the fun part (pushing cool new code), it got no response.

Because open-source projects survive on people having fun improving them.

There just isn't that many people working on the Rust language as a day job, and they all have their hands full. Some of them have been working on foundational stuff that is required to get async rust to work, but it's work taking place over years.

To give an example, the Inside Rust blog recently posted [1] an article about the Rust Trait System Refactor initiative, which is a refactor of one of most complex chunks of the rustc compiler, started earlier this year.

That refactor is required to unlock some advanced lifetime syntax. Advanced lifetime syntax is required for some specific GAT improvements. GAT improvements are required to unlock async traits.

It's not just "people are too lazy to write the documentation". A lot of thought went into this.

[1] https://blog.rust-lang.org/inside-rust/2023/07/17/trait-syst...

Re: Local async executors and why they should be the default

#124

Just 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…

[dead]

Re: Local async executors and why they should be the default

#125
post #113

Just 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…

> Where did it come from in its current incarnation? Node.

Rust's async/await is inspired by C# (which was inspired by F#, which was inspired by Haskell).

> right now threaded code is straight-up a better option on almost every metric,

Agreed that people are generally too eager to reach for async when they could easily get away with threads, and fortunately Rust makes threads extremely pleasant to work with. The whole point of Rust is that it doesn't force you to use any given paradigm when it comes to concurrency/parallelism, and has support for many approaches.

Re: Local async executors and why they should be the default

#126
post #35

I find all the async stuff in Rust incredibly ugly, cumbersome, and its one of the biggest reasons I prefer C++, still. C++ lets me just write single- or multithreaded code, because none of the dependencies force their `async` stuff on me. Yeah, its up to me to ensure things are synchronized, but I'd rather do that than try to figure out how to get some dependency that isnt meant to use async to work in some async mo…

> but I'd rather do that than try to figure out how to get some dependency that isnt meant to use async to work in some async move closure tokio::spawn_blocking [1], see it's not that hard. But sure to use another language you must learn it, an it requires a bit if effort… [1] assuming you want to use tokio like post people do, but other executors should have the same kind of functions to do that as well if need be.

You've made the giant assumption that most people working in Rust are working with some kind of executor or framework, and you're either wrong, or the state of the Rust world has become very depressing.

tokio::spawn_blocking doesn't exist in my codebase because I'm not using tokio, nor should I have to in order to use library code from a crate.

This is the problem with async in a nutshell; it's viral, and it brings with it a lot of lifestyle assumptions. Assumptions that I think people who are used to working in the web framework world are maybe comfortable with, but which should not have been allowed to spread to the crates ecosystem broadly.

async is fine as an implementation option for your service or binary; but its propagation into library code means now people using that library are tied into requiring a framework to host it with. And this is frankly just bad hygiene, and in a way seems contrary to Rust philosophy generally.

Most crate writers are polite enough to offer async and non-async bundling of their code. But on more than one occasion recently I've run into dependencies that did not do this, or did not do this thoroughly (offering sync versions with less features, for example).

Re: Local async executors and why they should be the default

#127

Earlier quoted context omitted.

The fun part is over. At least that is how a rust maintainer described it to me. When I asked why doing the unfun part (documentation, maintenance, etc.) isn't a condition for allowing people to do the fun part (pushing cool new code), it got no response.

Because open-source projects survive on people having fun improving them. There just isn't that many people working on the Rust language as a day job, and they all have their hands full. Some of them have been working on foundational stuff that is required to get async rust to work, but it's work taking place over years. To give an example, the Inside Rust blog recently posted [1] an article about the Rust Trait Syst…

[dead]

Re: Local async executors and why they should be the default

#128
post #79
post #59

Earlier quoted context omitted.

Technically true, but in practice you’re constrained by whatever is provided by the ecosystem. And the truth is that many Rust projects were forced to choose async or sync, so these are often disjoint and fragmented. Even within async, crate authors need to pick and choose which async ecosystem to support, due to lack of support in std for spawning tasks and running simple IO, which most projects need. This is slight…

Libraries don't just sprout out from nothingness, someone has written those. And if there isn't a library that suits you, that someone can be you then. Key observation is that the ecosystem is only additive, it doesn't deny you of anything.

This is true to an extant, except it's also a cultural problem: it spreads across crates, and soon you've got tokio spread everywhere.

But it's also a concern for me that a language feature was added that requires runtime framework support to function. This is bad separation of concerns.

It (async) is viral syntactic sugar that doesn't need to exist; asynchronous programming has been done for decades without it.

Re: Local async executors and why they should be the default

#129

Earlier quoted context omitted.

The fun part is over. At least that is how a rust maintainer described it to me. When I asked why doing the unfun part (documentation, maintenance, etc.) isn't a condition for allowing people to do the fun part (pushing cool new code), it got no response.

Because open-source projects survive on people having fun improving them. There just isn't that many people working on the Rust language as a day job, and they all have their hands full. Some of them have been working on foundational stuff that is required to get async rust to work, but it's work taking place over years. To give an example, the Inside Rust blog recently posted [1] an article about the Rust Trait Syst…

[flagged]

Re: Local async executors and why they should be the default

#130
Moaning aside, what is (if any?) the direct equivalent to single-threaded asyncio, like Python or node.js, in Rust?

The thing I enjoy about async in Python is that it's very easy to write "thread"-safe code - you know exactly where you might give up execution context, and 90% of the time you have no need for mutexes and locks. But as this article complains, in Rust, it seems to be sync or multi-threaded.

Post reply on HN