Live data from Hacker News

How to think about async/await in Rust

cliffle.com

231–240 of 268 posts

Re: How to think about async/await in Rust

#231

Not specific to rust, but I think asynchronous programming in general is a hype. It didn't start because it is so awesome, it started because JS can't do parallel any other way. That's the long and short of it. People wanted to use JS in the backend for some reason. The backend requires concurrency. JS cannot do concurrency. Enter the event loop. Then enter some syntactic sugar for the event loop. And since JS is pop…

> it started because JS can't do parallel any other way

There are two different subcultures pushing for asynchronous. You are correct, one is based on people learning to program in JS and suffering from either Stockholm syndrome or some other problem that blocks them from thinking in sequential IO.

The other grew mostly out of the 10k problem at the late 00's, and is very correct on their assessment in that asynchronous code allows for some high-performing architectures that are much better than anything you can get synchronously.

Those two groups are trying to solve different problems, with different architectures, in different parts of the software stack. Rust's async supports both of them, so the discourse is really confusing.

Re: How to think about async/await in Rust

#232

Concurrency is like a single cook preparing many different recipes at the same time, and parallelism is multiple cooks in the same kitchen. Single-threaded processes can use async/await to context switch and it feels like parallelism but it's not unless you're executing each task to its own OS thread. ... and that didn't click for me until I understood that concurrency (async/await) and parallelism (multiple OS threa…

Yeah, async is a type of greenthreading.

When I read async, I think about an event loop in a single thread.

Meanwhile when I read greenthreading, I think of lightweight threads like goroutines or Java's virtual threads.

Am I wrong?

Re: How to think about async/await in Rust

#233
post #232

Earlier quoted context omitted.

Yeah, async is a type of greenthreading.

When I read async, I think about an event loop in a single thread. Meanwhile when I read greenthreading, I think of lightweight threads like goroutines or Java's virtual threads. Am I wrong?

Right. Both of them are running on a single OS thread with application-layer context switching. Async's form of context switching is the event loop, greenthreading's is something analogous to OS threads.

Maybe it's inaccurate to say async is a type of greenthreading and better to say it's a form of application-layer context-switching comparable to greenthreading.

Re: How to think about async/await in Rust

#234
post #195

Earlier quoted context omitted.

Correct, I believe it originated with Microsoft via .Net in the mid-2000s and was picked up by the JS ecosystem much later. The fact that Microsoft had a hand in async/await’s emergence may influence how people feel about it.

> The fact that Microsoft had a hand in async/await’s emergence may influence how people feel about it. I can see this.

This whole thread reads like backlash to the async hype, not so much the merits of the paradigm itself.

Re: How to think about async/await in Rust

#235
post #155
post #124

Earlier quoted context omitted.

> It didn't start because it is so awesome, it started because JS can't do parallel any other way. That's the long and short of it If the comment is not conflating concurrency and parallelism as you say, mind expanding on this part?

But concurrency is just "single core parallelism" anyways, so this isn't really germane to the discussion. JS has neither.

Concurrency is not "single core parallelism". Concurrency describes tasks/threads of execution making independent progress of each other. Parallelism describes tasks/threads actually running at the same time.

Re: How to think about async/await in Rust

#236
post #93

Earlier quoted context omitted.

> One advantage of async/await is that its easier to cancel things. For example, this leads to the design pattern where you have multiple futures and you want to select the one that finishes first and cancel the rest. > In regular threaded programming, cancellation is a bit more painful as you need to have some type of cancellation token used each time the thread waits for something. This a) is more verbose and b) ca…

Since rust follows RAII, any and all resources allocated in the context should be deallocated when their destructor (the drop trait) is called. The unfortunate exception to this are resources which require an async call to deallocate properly. Though this can be worked around and there is work being done to fix this properly.

only if the resources are just used within this task. If an async function at some point in time generates another task (or even spawns a thread!) that can not be synchronously cancelled then it might outlive the destructor and thereby the async task. It's therefore nowhere near guaranteed that every Future can just be dropped to stop an action in a side-effect free fashion.

Re: How to think about async/await in Rust

#237

Earlier quoted context omitted.

There are use cases where a thread pool doesn't solve your problem. If you're handling a few short-lived connections at a time, it's more than enough, but if you're developing something like a push / messaging / queuing service, with thousands of clients connected for hours at a time and receiving very little data once every few minutes, a thread pool won't help you.

> a thread pool won't help you. What do you see as the main limitations of spawning 2048 threads in a pool in this scenario?

2048 threads would be fine, but they are talking about 10s of thousands of clients.

Re: How to think about async/await in Rust

#238
post #42

Earlier quoted context omitted.

>Not specific to rust, but I think asynchronous programming in general is a hype. Hmm, wasn't the whole point of doing things in event loop because it way out perform thread-based architecture? Like when Nginx way out performs Apache? On a single core CPU of course. Edit: It is not that event-loop is better than thread-based, just in a web server scenario it just perform much better.

The parent comment mentions green threads. While there is some performance hit to using them, I don’t think it is way less performant. I mean, go was built for being a web backend, and is based on green threads. For rust specifically, though, green threads/coroutines were discarded because they are not zero-cost.

Until go 1.14 it basically the same as any other async/await under the hood. Every function call included an implicit .await - that is it offered a `yield` to the runtime scheduler. All the io was built around non-blocking/polling, etc. Tight loops in go would potentially screw up your app performance because there were no yields. In 1.14 they introduced some sort of preemption for tight loops too.

Re: How to think about async/await in Rust

#239
post #194

Earlier quoted context omitted.

I thought the primary purpose of web workers was that the browser can run the workers in parallel to the main thread. As the spec says: > [Web workers] allow long tasks to be executed without yielding to keep the page responsive

The workers don't block painting and they do not run in a separate process. That's why it's concurrent but not parallel. The web worker does work whenever the main thread is not painting and there is a free time slot. The browser is not painting all the time. You don't get extra calculation performance with web workers. You just create the illusion of a smooth experience because you don't block painting. It does not…

Threads can certainly run in parallel with one another if the OS schedules them on different cores. I did a quick experiment and the main thread and worker threads run in parallel.

https://github.com/jschaf/web-worker-experiment/

> You don't get extra calculation performance with web workers

The primary purpose of web workers is extra calculation performance. From MDN:

> Workers are mainly useful for allowing your code to perform processor-intensive calculations without blocking the user interface thread

Re: How to think about async/await in Rust

#240
post #239

Earlier quoted context omitted.

The workers don't block painting and they do not run in a separate process. That's why it's concurrent but not parallel. The web worker does work whenever the main thread is not painting and there is a free time slot. The browser is not painting all the time. You don't get extra calculation performance with web workers. You just create the illusion of a smooth experience because you don't block painting. It does not…

Threads can certainly run in parallel with one another if the OS schedules them on different cores. I did a quick experiment and the main thread and worker threads run in parallel. https://github.com/jschaf/web-worker-experiment/ > You don't get extra calculation performance with web workers The primary purpose of web workers is extra calculation performance. From MDN: > Workers are mainly useful for allowing your co…

I should clarify that you can't get extra calculation performance which easily scales with core count due to the gotchas around threading that you mentioned.
Post reply on HN