Live data from Hacker News

Why asynchronous Rust doesn't work

theta.eu.org

311–320 of 499 posts

Re: Why asynchronous Rust doesn't work

#311
This was a great article, very easy to understand without leaving out the fundamental pieces (the saga that is async implementation difficulty). I think I can even boil this situation down to the simple thought that design & implementation of async in Rust has driven it to it's first "monad" moment. The question is now largely whether there exists a way that is better than monads to handle this problem.

It's in this (HN) comment thread and a bunch of informed comments on the original article:

https://github.com/eeeeeta/blog-comments/issues/10#issuecomm...

https://github.com/eeeeeta/blog-comments/issues/10#issuecomm...

https://github.com/eeeeeta/blog-comments/issues/10#issuecomm...

The comments are correct in my view -- Rust can't/shouldn't do what Haskell did, which was to create use a general purpose abstraction that is essentially able to carry "the world" (as state) along with easy-to-trade chained functions on that state (whenever it gets realized). Haskell might have solved the problem, but it has paid a large price in language difficulty (perceived or actual) because of it, not mentioning the structural limitations of what Rust can do and it's constraints. The trade-off just isn't worth it for the kind of language Rust aims to be.

Realistically, I think this issue is big but not enough to write off rust for me personally (as the author seems to have) -- I'd just do the move + Arc shenanigans because if you've been building java applications with IoC and/or other patterns that generally require global-ish singletons (given example was a DB being used by a server), this isn't the worst complexity trade-off you've had to make, though the Rust compiler is a lot more ambitious, and Rust has a cleaner, better, more concise type system as far as I'm concerned.

I think another thing I've gained from this article is another nice little case where Haskell (if you've taken the time to grok it sufficiently, which can be a long time) offers a bit of a nicer general solution than Rust, assuming you were in a world where those two were actually even substitutes. In the much more likely world where you might compare Rust and Go2, this might be a win for Go2, but the rest of the language features would put rust on top for me.

Re: Why asynchronous Rust doesn't work

#312

Earlier quoted context omitted.

>Our async IO model was based on the Linux industry standard (then and now) epoll, but that is not at all what drove the switch to a polling based model Can you provide a link to a design document or at the very least to a discussion with motivation for this switch outside of the desire to be as compatible as possible with the "Linux industry standard"? >the polling based model presents no issues whatsoever with io-u…

https://aturon.github.io/blog/2016/09/07/futures-design/ The completion based futures that Alex started with were also based on epoll. The performance issues it presented had nothing to do any sort of impedence mismatch between a completion based future and epoll, because there is no impedence issue. You are confused.

Thank you for the link! But immideately we can see the false equivalence: completion based API does not imply the callback-based approach. The article critigues the latter, but not the former. Earlier in this thread I've described how I see a completion-based model built on top of FSMs generated by compiler from async fns. In other words, the arguments presented in that article do not apply to this discussion.

>The performance issues it presented had nothing to do any sort of impedence mismatch between a completion based future and epoll

Sorry, but what? Even aturon's article states zero-cost as one of the 3 main goals. So performance issues with strong roots in the selected model is a very big problem in my book.

>You do not know what you are talking about.

>You are confused.

Please, tone down your replies.

Re: Why asynchronous Rust doesn't work

#313
post #303

Earlier quoted context omitted.

This post is completely and totally wrong. At least you got to ruin my day, I hope that's a consolation prize for you. There is NO meaningful connection between the completion vs polling futures model and the epoll vs io-uring IO models. comex's comments regarding this fact are mostly accurate. The polling model that Rust chose is the only approach that has been able to achieve single allocation state machines in Rus…

Is it just me or you're supporting your parent's point of: > ...the decision was effectively made on the ground of "we want to ship async support as soon as possible" [1]. When you write: > Moreover, getting a usable async/await MVP was absolutely essential to getting Rust the escape velocity to survive the ejection from Mozilla... This whole situation saddens me. I wish Mozilla could have given you guys more breathi…

That is not a correct reading of the situation. async/await was not rushed, and does not have flaws that could have been solved with more time. async/await will continue to improve in a backward compatible way, as it already has since it was released in 2019.

Re: Why asynchronous Rust doesn't work

#314
post #57

I like to joke that the best way to encounter the ugliest parts of Rust is to implement an HTTP router. Hours and days of boxing and pinning, Futures transformations, no async fn in traits, closures not being real first class citizens, T: Send + Sync + 'static, etc. I call this The Dispatch Tax. Because any time you want more flexibility than the preferred static dispatch via generics can give you - oh, so you just w…

Definitely dynamic dispatch + async brings out a lot of pain points.

But I only agree that the async part of that is unfortunate. Making dynamic dispatch have a little extra friction is a feature, not a bug, so to speak. Rust's raison d'être is "zero cost abstraction" and to be a systems language that should be viable in the same spaces as C++. Heap allocating needs to be explicit, just like in C and C++.

But, I agree that async is really unergonomic once you go beyond the most trivial examples (some of which the article doesn't even cover).

Some of it is the choices made around the async/await design (The Futures, themselves, and the "async model" is fine, IMO).

But the async syntax falls REALLY flat when you want an async trait method (because of a combination-and-overlap of no-HKTs, no-GATs, no `impl Trait` syntax for trait methods) or an async destructor (which isn't a huge deal- I think you can just use future::executor::block_on() and/or use something like the defer-drop crate for expensive drops).

Then it's compounded by the fact that Rust has these "implicit" traits that are usually implemented automatically, like Send, Sync, Unpin. It's great until you write a bunch of code that compiles just fine in the module, but you go to plug it in to some other code and realize that you actually needed it to be Send and it's not. Crap- gotta go back and massage it until it's Send or Unpin or whatever.

Some of these things will improve (GATs are coming), but I think that Rust kind of did itself a disservice with stabilizing the async/await stuff, because now they'll never be able to break it and the Pin/Unpin FUD makes me nervous. I also think that Rust should have embraced HKTs/Monads even though it's a big can of worms and invites Rust devs to turn into Scala/Haskell weenies (said with love because I'm one of them).

Re: Why asynchronous Rust doesn't work

#315
post #166

Earlier quoted context omitted.

It's easy to convert an async function into a blocking one. For example, you could use https://docs.rs/async-std/1.9.0/async_std/task/fn.block_on.h... So just use the async functions from the library synchronously if you want.

But you can't really do vice-versa.

Well, you can use https://docs.rs/async-std/1.9.0/async_std/task/fn.spawn_bloc...

But this is partly the reason why libraries might be more inclined to support async rather than blocking calls.

Re: Why asynchronous Rust doesn't work

#316

Earlier quoted context omitted.

This post is completely and totally wrong. At least you got to ruin my day, I hope that's a consolation prize for you. There is NO meaningful connection between the completion vs polling futures model and the epoll vs io-uring IO models. comex's comments regarding this fact are mostly accurate. The polling model that Rust chose is the only approach that has been able to achieve single allocation state machines in Rus…

To hopefully make your day better. I for one, amongst many people I am sure, am deeply grateful for the work of you and your peers in getting this out!

I second this. Withoutboats has done some incredible work for Rust.

Re: Why asynchronous Rust doesn't work

#317
post #132

This is pretty overblown. I write async rust every day for my job, just fine, with no real problems. Probably because I'm consuming other libraries, I'm not trying to write my own. I use well-tested libraries like Actix-Web or occasionally Tokio. I've migrated multiple projects from futures to async/await once the syntax came out. ' The problems the author is describing might apply more to library authors, but for th…

Agreed, I rewrote a 10k line a js websocket based game server[0] a few months ago into async Rust. It was mostly painless

I didn't have to deal with closures much because I'm comfortable writing a 2000 line match

0: https://github.com/serprex/openEtG/tree/master/src/rs/server

Re: Why asynchronous Rust doesn't work

#318
post #299
post #232

Earlier quoted context omitted.

Yes, indeed. Yet, this is the problem to solve. I don't know if you are using Rust, but what would you say, why is that? Where does that motivation come from?

I've been developing mostly in Rust for the last five years. C++ for decades before that. It is always comforting to dismiss something that you haven't made much effort to understand as unnecessarily overcomplex. I think we're all guilty of that at times.

Ah, i see. But the systems crowd (I'm going to lump them all together: microcontroller, kernel, high performance networking, etc.) is supposed to be the main target audience. For me it is hard to believe that so many of them just brush it off as too complex on first sight.

On the other hand, maybe those folks decided, after giving it a serious try, it's not worth it. Mind you, that does not mean they are right. But in the end, if the effort for those people is perceived as too high, then maybe, just maybe, in practice it really is.

After more than 25 years as a developer, I learned the hard way, that programming languages, are, in the end, a matter of taste. You won't get someone to use a language, just by citing the feature list. Programming languages are a product made for developers. If they don't like it (for whatever reasons, and yes, these are at times highly subjective) they won't use it.

Re: Why asynchronous Rust doesn't work

#319

Earlier quoted context omitted.

That’s why it’s amazing, type safe efficient multi-threading without dynamic memory allocation with a nice syntax...it’s the holy grail of server programming.

Why would I want to write a server in a language that requires such awkward approaches to basics like coroutines and dynamic dispatch when I could use kotlin on the JVM and get pauseless GC, ultra fast edit/compile/run cycles, efficient and powerful coroutines, and eventually Loom which will eliminate the whole problem of coloured functions completely and let me just forget about coroutines? Multi threading bugs are…

Have you ever tried writing the same application on both a JVM language and in Rust, and then measuring the latency & throughput differentials? Blew my mind the first time.

Of course, if speed isn’t a concern for you, then please carry on.

Re: Why asynchronous Rust doesn't work

#320

> The thing I really want to try and get across here is that *Rust is not a language where first-class functions are ergonomic.* So... don’t use first-class functions so much? It’s a systems language, not a functional language for describing algorithms in CS whitepapers. Or use `move` (the article does mention this). There are easy paths in most programming languages, and harder paths. Rust is no exception. The fact…

I think your implication that a system programming language can't have nice stuff is based on system languages of old. Unless a language is absolutely must have manual memory allocations, it can have 1st class functions and closures.
Post reply on HN