zlacker

[parent] [thread] 17 comments
1. the_mi+(OP)[view] [source] 2024-01-23 12:34:44
I think the better way to think about async Rust is to use it when it's beneficial to developer productivity and to avoid it when not. There are quite a few situations where it makes the code easier compared to alternatives you could come up with.

I don't think for a second that async Rust should be picked for performance reasons.

You get a feeling for what is a good use of async and bad use of async relatively easily these days as the ecosystem is maturing.

replies(3): >>baq+01 >>ameliu+J1 >>zaphar+Q3
2. baq+01[view] [source] 2024-01-23 12:40:47
>>the_mi+(OP)
What arguments are there for async if not performance? Threads/fibers/gofuncs/actors/... are easier to reason about. Async is super helpful to avoid overhead of thousands of threads, but makes just about everything else harder.
replies(3): >>bryanl+A2 >>the_mi+E6 >>sshine+m8
3. ameliu+J1[view] [source] 2024-01-23 12:44:25
>>the_mi+(OP)
> I think the better way to think about async Rust is to use it when it's beneficial to developer productivity and to avoid it when not.

How do you know if what is best doesn't change as the project you're working on progresses and your manager tosses in new requirements?

I'd say better pick a technique (or even language) that works all the time.

replies(1): >>seanhu+h3
◧◩
4. bryanl+A2[view] [source] [discussion] 2024-01-23 12:50:29
>>baq+01
I disagree. I've got several programs with a async select based main loop and others with threads, and the former are easier to reason about in my opinion. Threads hide effects.

However, Tokio tries to be the best of both threads and async and sometimes ends up being the worst of both when Sync/Send/etc creep into function signatures.

◧◩
5. seanhu+h3[view] [source] [discussion] 2024-01-23 12:54:50
>>ameliu+J1
There isn’t one technique that works all the time. Life is unfortunately about tradeoffs whenever you do something complex.
replies(1): >>ameliu+j5
6. zaphar+Q3[view] [source] 2024-01-23 12:57:50
>>the_mi+(OP)
It is increasingly harder to avoid async Rust if you do any form of IO. Most of the useful io based crates assume you are doing async with a very minor amount of them giving you a non async api. Out of the ones that do they are bundling an executor to power that api because they don't want to implement it twice.

I think part of what is feeding this sort of backlash against it is the way that it creates two different rust ecosystems. One of them, the non async version, being decidedly a second class citizen.

replies(1): >>bryanl+k6
◧◩◪
7. ameliu+j5[view] [source] [discussion] 2024-01-23 13:09:42
>>seanhu+h3
So choose a technique and language that least limits your design freedom.

Choosing performance as your #1 priority is often a bad idea as it gets you into a straight-jacket from the start, making everything else much more difficult and slows down development to a crawl. Unless you're developing an OS kernel perhaps. Computers are fast enough these days, let them do part of the work for you! And you can always write a faster version of your software when there is a demand for it.

replies(1): >>sshine+Pb
◧◩
8. bryanl+k6[view] [source] [discussion] 2024-01-23 13:16:09
>>zaphar+Q3
It looks like there's good movement on the proposal to bring pollster[1] or similar into the Rust standard library.

I think that's awesome. They've been afraid to "bless" an executor for good reasons, but pollster has 0 chance of "winning" even if blessed since it lacks so many features. However it's a solution to the problem you expressed: I/O crates can be async and used with pollster in sync contexts.

1: https://docs.rs/pollster/latest/pollster/

replies(1): >>Aissen+Nf4
◧◩
9. the_mi+E6[view] [source] [discussion] 2024-01-23 13:18:41
>>baq+01
Async makes awaiting things much easier than other primitives in the language. So for instance if you both need to wait for stuff to happen on a socket or some event happening, async select makes that super easy.

You can also keep async relatively local to a function that does these things and is itself blocking otherwise.

replies(1): >>ameliu+s8
◧◩
10. sshine+m8[view] [source] [discussion] 2024-01-23 13:29:59
>>baq+01
I use (custom-made) actors and (Tokio) channels a lot, and I build them with async.

I do make separate threads when necessary (e.g. to encapsulate blocking I/O).

It can approximate an Erlang experience.

But with a lot more boilerplate and lack of good actor library patterns.

◧◩◪
11. ameliu+s8[view] [source] [discussion] 2024-01-23 13:30:37
>>the_mi+E6
Yes, async is easier, but granularity of performance is a real downside. The CPU is a resource too, and needs to be managed more carefully than async can do. There's a reason why people stopped using cooperative multitasking like in Windows 3.1 ...
replies(1): >>the_mi+Le
◧◩◪◨
12. sshine+Pb[view] [source] [discussion] 2024-01-23 13:52:14
>>ameliu+j5
> Choosing performance as your #1 priority is often a bad idea

You can write inefficient code and optimize it later.

> it gets you into a straight-jacket from the start, making everything else much more difficult and slows down development time to a crawl. Unless you're developing an OS kernel perhaps

The argument seems to break down: Surely you don't want to be in a strait-jacket if you're developing an OS kernel. Somehow Rust is equated with always being in a strait jacket.

The cost of writing highly concurrent programs is pretty much the same in every language except ones that have concurrency at the core (Erlang). I don't see much difference between starting with Java or Rust in terms of avoiding complexity caused by having to build things that a concurrent runtime could give to you for free.

replies(1): >>ameliu+Kk
◧◩◪◨
13. the_mi+Le[view] [source] [discussion] 2024-01-23 14:07:56
>>ameliu+s8
Sure, but that’s not really an argument for or against async but for or against different runtime policies.
replies(1): >>ameliu+aU
◧◩◪◨⬒
14. ameliu+Kk[view] [source] [discussion] 2024-01-23 14:35:06
>>sshine+Pb
> The argument seems to break down: Surely you don't want to be in a strait-jacket if you're developing an OS kernel.

If you're developing an OS, there is no escaping from the straight-jacket. Your design freedom is severely limited by the fact that your constraints include all applications that will run on your OS.

◧◩◪◨⬒
15. ameliu+aU[view] [source] [discussion] 2024-01-23 16:56:26
>>the_mi+Le
What good are "runtime policies" if you're in a single thread that you can't interrupt (which is what async is)?
replies(1): >>the_mi+Oe2
◧◩◪◨⬒⬓
16. the_mi+Oe2[view] [source] [discussion] 2024-01-23 22:54:08
>>ameliu+aU
Async is not really that in Rust. While it's true that a singular poll cannot be preempted, things like task::spawn schedule that on a multi threaded executor. So a lot of cases behave just like threads except you await them from somewhere else.
◧◩◪
17. Aissen+Nf4[view] [source] [discussion] 2024-01-24 15:58:17
>>bryanl+k6
I haven't been following, would you have a link to this proposal ? A quick search of pollster in rust-lang/rust and rust-lang/rfcs does not bring any interesting result.
replies(1): >>bryanl+kZ4
◧◩◪◨
18. bryanl+kZ4[view] [source] [discussion] 2024-01-24 19:37:51
>>Aissen+Nf4
Good question. I might have been projecting my hopes to make it sound more formal, but the only thing I could find following my cookie crumbs was the mention in https://without.boats/blog/why-async-rust/
[go to top]