Hacker News new | ask | show | jobs
by m_a_g 1472 days ago
I would like to add that async Rust still doesn't really work. That is a big negative for Rust.
3 comments

I've been using async Rust in production for years. The learning curve is a little higher than I'd like. But it works great and it does everything we need it to. For an open source example, see https://www.dbcrossbar.org/

Many problems with async Rust involve people trying to get overly clever with lifetimes and zero-copy code. And if it's not either of those, it's people getting overly clever with async traits. So keep it simple!

Some tips:

1. Long-running async tasks should own their data, not borrow it. This will save you 80% of the pain right there.

2. Don't be afraid to allocate futures on the heap, and use "Box<dyn Future<Output=T>>" to hide the implementation.

3. If you must use traits with async members, use "async_trait".

4. Remember that futures can be cancelled at any "await" point. You can ignore this 99% of the time, as long as you use destructors to perform cleanup.

I would only recommend async Rust if you actually need very high-performance async code. Regular threaded Rust still works great for most things, as do languages like TypeScript. But if you actually need what async Rust offers, it's totally workable.

This constant refrain must be discouraging to the people who have worked so hard on async rust. Can we please restrict our criticism to specific problems, and temper it with gratitude for the amazing things that the Rust developers have already given us free of charge?
I am not sure what is so "un-tempered" in the original message (assuming it is not technically incorrect) and what makes Rust so special that criticism must be "tempered with gratitude".
It's too vague. The claim is that async "still doesn't really work" but like, how so?

Sometimes you could make a claim like that about a feature and it's more or less accurate just as it stands. C++ 20 Modules were like that (still might be like that?) on most platforms, 'cos it turns out that's a lot of work for a compiler to implement and it's important to say you have the feature even if you know it doesn't work well. But even then, I'd rather see e.g. "C++ 20 Modules blow up if I try to A, or B, or C... or Z" it's just that I can understand if your list is a page long "doesn't really work" seems more concise than listing everything.

There are clearly people who are frustrated by aspects of Rust's async. Some of those frustrations are fixable, some are consequences of a principle decision that's unlikely to be revisited, and who knows if you won't say what frustrated you

Suppose I said Go's generics "don't really work". Do I mean that they aren't monomorphised in the way I hoped? That the syntax is too untidy for me? That the Go libraries aren't yet making them ergonomic? That I found a compiler bug? No way to know.

I understand and agree with what you say. It is ""tempered with gratitude" part of the original message I do not grok.
Well, I have several production services. They are written in async rust. If they didn't work, or worked poorly, or even worked sorta good - you'd know it, the outages would be front page news in the tech press and maybe even on "the news".

I didn't have to do anything special to make them work well, just out of the box tokio and a small bit of learning how to do stuff that's weird to do in most any language (e.g. netlink, bpf maps and so on).

I don't know what the definition of "doesn't really work" is, but it seems technically incorrect given how my services run for months at a time between restarts (which I consider a symptom of working).

Rust isn't special; what I said applies to any open-source project. But people have been pretty harsh about async in Rust lately, and IMO the message I was replying to makes the problem sound worse than it is.
Lol. just replace Rust with C++/Java. Does your opinion change ? Because no one cares about being gentle to C++/Java in the HN community.
It definitely works just fine
My main issue with Rust async was that it wasn't possible to write a "runtime agnostic" libraries. For example, I wrote an HTTP client with Tokio and later wanted to use it in a project that was using another runtime (I think it was async-std) and couldn't use it. I wonder if that has changed since then?
That's basically only a problem if you use async-std (just don't, and switch your project if you have). Pretty much everything supports tokio (or there is a just-as-good equivalent library that supports tokio).

Which isn't to say this shouldn't be fixed. Just that there's a fairly good away to avoid the problem in practice.

This is probably more of a concern for people who aren't writing services/ professional devs. Otherwise, who cares, you pick a runtime (tokio) and you use it - runtime agnosticism isn't a real goal for any company.
You can find great examples of Rust async programming being "a disaster and a mess". You still can consider it is working just fine, but I disagree.
I don't really need to find those examples, I've written most of my company's product in Rust using async, for years, and it's never once been an issue. That's 100s of thousands of lines of rust written and 0 async issues.
Totally valid, but you could also say the same thing about C and C++, i.e. you can wield your tool with mastery, then that's awesome. But I think the average startup would likely struggle needlessly when they really just need to ship products that people want/need to use. Rust is likely not the smartest choice for the average startup.
Only one person at the company had previous professional experience with Rust. The majority had 0 experience with it at all. We've had no trouble and it's actually been our most productive language - we're moving away from Python and Typescript where possible.