Live data from Hacker News

How to think about async/await in Rust

cliffle.com

41–50 of 268 posts

Re: How to think about async/await in Rust

#41
post #15

I think Go got it right by inverting the logic around async/await. In Go you have to explicitly state that a function is to run in the background via "go fn(...)". This makes it much clearer that this code will execute concurrently. In the async/await world you can't tell by looking at a function call if it will block until it's done. Forgot an await? No compile error but your program might behave in weird ways. This…

> Haven't done too much async Rust yet but I don't think it solved this issue from what I've seen.

In Rust an async function is really just a const fn that synchronously only constructs and returns a state machine struct that implements the Future trait.

So

async fn foo(x: i32) { }

essentially desugars to

const fn foo(x: i32) -> FooFuture { FooFuture { x } }

struct FooFuture { x: i32 } // technically it's an enum modelling the state machine

impl Future for FooFuture { ... }

You have to explicitly spawn that onto a runtime or await it (i.e. combine it into the state machine that your code is already in). So that's actually really cool about how Rust handles async; that an async fn really isn't doing any magic, it just constructs a state machine and never interacts (or spawns) with a runtime at all, so it never starts running in the background, you are always in full control. And by throwing the future away, you are essentially cancelling it, there's no need to interact with any runtime either.

Re: How to think about async/await in Rust

#42

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…

>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.

Re: How to think about async/await in Rust

#43

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…

Look at this program:

    val another_path = await readFile(path);
    val data = await readFile(another_path);
    console.log(data.length);
How would you do that using threads?

Re: How to think about async/await in Rust

#44

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…

Most languages don't have preemptively scheduled green threads like golang.

In Lua and Zig we have "cooperative multitasking" but we get to use the same library for both kinds of applications :)

Re: How to think about async/await in Rust

#45

Earlier quoted context omitted.

It began in C# in 2012 - 5 years before JavaScript. And C# does threads. And made its way to JavaScript via Typescript (whose creator also created C#).

Maybe I'm misunderstanding what you mean by "It began in C#", but F# introduced async about five years before C# 5 was released.

I know it influenced the async await design, but I didn't think it was quite the same. Will go do some reading!

Re: How to think about async/await in Rust

#46

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…

Look at this program: val another_path = await readFile(path); val data = await readFile(another_path); console.log(data.length); How would you do that using threads?

This program has no concurrency so you could do it without threads.

Re: How to think about async/await in Rust

#47

Earlier quoted context omitted.

It began in C# in 2012 - 5 years before JavaScript. And C# does threads. And made its way to JavaScript via Typescript (whose creator also created C#).

Maybe I'm misunderstanding what you mean by "It began in C#", but F# introduced async about five years before C# 5 was released.

could be wrong about c#, but c# and f# are comes from same parent

Re: How to think about async/await in Rust

#48

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…

Look at this program: val another_path = await readFile(path); val data = await readFile(another_path); console.log(data.length); How would you do that using threads?

uh, open a thread that does that and `join` on it waiting for it to complete, but why would you need that in your example?

Re: How to think about async/await in Rust

#49

Earlier quoted context omitted.

Look at this program: val another_path = await readFile(path); val data = await readFile(another_path); console.log(data.length); How would you do that using threads?

This program has no concurrency so you could do it without threads.

Not in Rust if you use something like Tokio.

Re: How to think about async/await in Rust

#50
post #26
post #22

Earlier quoted context omitted.

> Haven't done too much async Rust yet but I don't think it solved this issue from what I've seen. If you don't await your variable contains a future - how are you using that like e.g. an int, without a compiler error?

The issue arises if you don't use the returned value. Lets say there's a function "async fn saveToDisk()". You call this function before you exit the program. Now if you forget to use await on it, your program will exit without having saved the data to disk.

In any sensible API, saveToDisk would return an error status (a Result type in Rust). If you don't check for errors, then probably you didn't care of the data was actually saved or not.
Post reply on HN