Live data from Hacker News

Why asynchronous Rust doesn't work

theta.eu.org

381–390 of 499 posts

Re: Why asynchronous Rust doesn't work

#381
post #372

Earlier quoted context omitted.

As I've mentioned several times, in this model you can not simply "drop the task" without running its asynchronous Drop. Each state in FSM will be generated with a "drop" transition function, which may include asynchronous cancellation requests (i.e. cleanup can be bigger than one transition function and may represent a mini sub-FSM). This would require introducing more fundamental changes to the language (same as wi…

“Rust would have been a better language by breaking its stability guarantees” is just saying “Rust would have been a better language by not being Rust.” Maybe true, but not relevant to the people whose work you’ve blanket criticized. Rust language designers have to work within the existing language and your arguments are in bad faith if you say “async could have been perfect with all this hindsight and a few breaking…

I do not think that impossibility of a reliable async Drop in Rust 1 is a proven thing (prior to the stabilization of async in the current form). Yes, it may require some unpleasant additions such as making Futures and async fns more special than they are right now and implementing it with high probability would have required a lot of work (at least on the same scale as was invested into the poll-based model), but it does not make it impossible automatically.

Re: Why asynchronous Rust doesn't work

#382
post #378

Earlier quoted context omitted.

> Please, tone down your replies. You cannot literally make extremely inflammatory comments about people's work, and accuse them of all sorts of things, and then get upset when they are mad about it. You've made a bunch of very serious accusations on multiple people's hard work, with no evidence, and with arguments that are shaky at best, on one of the largest and most influential forums in the world. I mean, you can…

I found it highly critical but not inflammatory - though I'm not sure if I'd've felt the same way had they been being similarly critical of -my- code. However, either way, responding with condescension (which is how the 'industry standard' thing came across) and outright aggression is never going to be constructive, and if that's the only response one is able to formulate then it's time to either wait a couple hours…

Of course I was more gracious to pornel - that remark was uncharacteristically flippant from a contributor who is normally thoughtful and constructive. pornel is not in the habit of posting that my work is fatally flawed because I did not pursue some totally unviable vaporware proposal.

Re: Why asynchronous Rust doesn't work

#383

Earlier quoted context omitted.

I do not put words in their mouth or have you missed the "in my opinion" part? The issues with Pin, problems around noalias, inability to design a proper async Drop solution, not a great compatibility with io-uring and IOCP. In my eyes they are indicators that Rust health in the async field has suffered. >Completion based is totally better and the only reason it wasn't done was because it would take too long and Rust…

Isn't it very likely that going the other route would also result in a different but equally long list of issues?

Yes, it's a real possibility. But the problem is that the other route was not properly explored, so we can not compare advantages and disadvantages. Instead Rust went all-in on a bet which was made 3 years ago.

Re: Why asynchronous Rust doesn't work

#384

Earlier quoted context omitted.

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…

Good luck getting Google's ad backend with 20ms latency budget and billions of dollars of revenue approved with the JVM. Therr are many tasks where what you suggests is just too slow and unpredictable. Don't get me wrong, I think JVM is great, it's just not systems level programming.

Modern JVM GCs have pause times below 1msec. That's a new capability though so most people aren't yet aware of it.

And Google's ads backend are hardly the definition of server. Their ads front-end for example always used to be in Java. Not sure what it is these days

Re: Why asynchronous Rust doesn't work

#385

A bigger problem in my opinion is that Rust has chosen to follow the poll-based model (you can say that it was effectively designed around epoll), while the completion-based one (e.g. io-uring and IOCP) with high probability will be the way of doing async in future (especially in the light of Spectre and Meltdown). Instead of carefully weighing advantages and disadvantages of both models, the decision was effectively…

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…

I've jumped on the Rust bandwagon as part of ZeroTier 2.0 (not rewriting its core, but rewriting some service stuff in Rust and considering the core eventually). I've used a bit of async and while it's not as easy as Go (nothing is!) it's pretty damn ingenious for language-native async in a systems programming language.

I personally would have just chickened out on language native async in Rust and told people to roll their own async with promise patterns or something.

Ownership semantics are hairy in Rust and require some forethought, but that's also true in C and C++ and in those languages if you get it wrong there you just blow your foot off. Rust instead tells you that the footgun is dangerously close to going off and more or less prohibits you from doing really dangerous things.

My opinion on Rust async is that it its warts are as much the fault of libraries as they are of the language itself. Async libraries are overly clever, falling into the trap of favoring code brevity over code clarity. I would rather have them force me to write just a little more boilerplate but have a clearer idea of what's going on than to rely on magic voodoo closure tricks like:

https://github.com/hyperium/hyper/issues/2446

Compare that (which was the result of hours of hacking) to their example:

https://hyper.rs/guides/server/hello-world/

WUT? I'm still not totally 100% sure why mine works and theirs works, and I don't blame Rust. I'd rather have seen this interface (in hyper) implemented with traits and interfaces. Yes it would force me to write something like a "factory," but I would have spent 30 minutes doing that instead of three hours figuring out how the fuck make_service_fn() and service_fn() are supposed to be used and how to get a f'ing Arc in there. It would also result in code that someone else could load up and easily understand what the hell it was doing without a half page of comments.

The rest of the Rust code in ZT 2.0 is much clearer than this. It only gets ugly when I have to interface with hyper. Tokio itself is even a lot better.

Oh, and Arc gets around a lot of issues in Rust. It's not as zero-cost as Rc and Box and friends but the cost is really low. While async workers are not threads, it can make things easier to treat them that way and use Arc with them (as long as you avoid cyclic structures). So if async ownership is really giving you headaches try chickening out and using Arc. It costs very very little CPU/RAM and if it saves you hours of coding it's worth it.

Oh, and to remind people: this is a systems language designed to replace C/C++, not a higher level language, and I don't expect it to ever be as simple and productive as Go or as YOLO as JavaScript. I love Go too but it's not a systems language and it imposes costs and constraints that are really problematic when trying to write (in my case) a network virtualization service that's shooting (in v2.0) for tens of gigabits performance on big machines.

Re: Why asynchronous Rust doesn't work

#386

Earlier quoted context omitted.

Note that C++ offers async as a library and not as a programming language feature which Bjarne Stroustrup is strongly against. He talk more about why in "The Design and Evolution of C++" but i don't have the material at hand. As far as i remember, his main argument was that there is no concurrency model to fit them all and thus it doesn't worth to add new syntax and semantics for a specific model except to make the P…

> Note that C++ offers async as a library and not as a programming language feature which Bjarne Stroustrup is strongly against. https://www.modernescpp.com/index.php/c-20-coroutines-the-fi...

There's no executor in the standard library for asynchronous work, the C++20 coroutines implementation lets you plug in your own

Dummy event loop example:

https://gcc.godbolt.org/z/fo18xW

Re: Why asynchronous Rust doesn't work

#387
We all start out loving callbacks, eventually progress to coroutines, and finally end up writing polling loops. It took me more than 30 years to figure this out.

I understand completely why most people disagree - I always disagreed even louder.

Re: Why asynchronous Rust doesn't work

#388

Earlier quoted context omitted.

> [async] “colorless” I’m super interested that you think that’s something that can exist, how would it work, what would it look like in your mind ?

Zig does it ( https://kristoff.it/blog/zig-colorblind-async-await/ ). Basically using "await" just means you are declaring opportunity for concurrency at the call site, but it is still valid to await a synchronous function. And it is valid to call a function synchronously, even if it internally supports concurrency via await.

Yes, that's a very clear and concise way of putting it, thanks.

Re: Why asynchronous Rust doesn't work

#389
post #237

Earlier quoted context omitted.

> A bigger problem in my opinion is that Rust has chosen to follow the poll-based model This is an inaccurate simplification that, admittedly, their own literature has perpetuated. Rust uses informed polling: the resource can wake the scheduler at any time and tell it to poll. When this occurs it is virtually identical to completion-based async (sans some small implementation details). What informed polling brings to…

Could you explain what is informed and stateless informed polling? I haven't really found anything on the web. Thanks!

So stateful async would be writing IO. You've passed in a buffer, the length to copy from the buffer. In the continuation, you'd need to know which original call you were working with so that you can correlate it with those parameters you passed through.

    var state = socket.read(buffer);
    while (!state.poll()) {}
    state.bytesRead...
Stateless async is accepting a connection. In 95% of servers, you just care that a connection was accepted; you don't have any state that persists across the continuation:

    while (!listeningSocket.poll()) {}
    var socket = listeningSocket.accept();
Stateless async skirts around many of the issues that Rust async can have (because Pin etc. has to happen because of state).

Re: Why asynchronous Rust doesn't work

#390
post #9

I don't know rust good enough but the article sounds like 'I can't write it like I want, therefore it's bad'. Couldn't he just pass a named function instead of an anonymous one?

No, he could not. The problem emerges when trying to use state (a database connection, in the author's example) in the callback function. That requires a closure (or a managed global, but that's not zero-cost).

Thanks for the clarification
Post reply on HN