Live data from Hacker News

Async-await on stable Rust

blog.rust-lang.org

81–90 of 392 posts

Re: Async-await on stable Rust

#82

I’ve been playing with async await in a polar opposite vertical than its typical use case (high tps web backends) and believe this was the missing piece to further unlock great ergonomic and productivity gains for system development: embedded no_std. Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming wi…

It's like old Windows programming (Windows 3.X). Cooperative multitasking is process control version of manual unsafe memory management. When your app suddenly freezes, you discovered a bug.

It's for cases where alternatives don't exist or they are too expensive.

Language level green threads are safer abstraction over asynchronous I/O operations.

Re: Async-await on stable Rust

#83
post #75
post #62

This is a major milestone for Rust usability and developer productivity. It was really hard to build asynchronous code until now. You had to clone objects used within futures. You had to chain asynchronous calls together. You had to bend over backwards to support conditional returns. Error messages weren't very explanatory. You had limited access to documentation and tutorials to figure everything out. It was a proce…

Is there any resources you could point to learn more about how to use this async programming with?

https://rust-lang.github.io/async-book

https://book.async.rs

https://tokio.rs

Re: Async-await on stable Rust

#84
post #71
post #60

Earlier quoted context omitted.

I don't like this at all. Having to rely on futures::join! means that I don't have the flexibility to control the execution of these things unless Rust adds that specific utility, right? In JS, for example, the `bluebird` library is a third party utility for managing execution of functions. You can do things like const results = await Promise.map(users, user => saveUserToDBAsync(user), { concurrency: 5}); And I pass…

It feels like you're complaining about things in the Rust language without taking the time to understand how the language idioms work. RTFM. Additionally, you're making snarky comments about how you don't like how the base language doesn't handle something like JS...then reference a third party JS library. Base JS doesn't solve your 'problem' either. To answer your question, async/await provides hooks for an executor…

[deleted]

Re: Async-await on stable Rust

#85
post #60

Earlier quoted context omitted.

In Rust, you can use a future adapter that does this: futures::join!(asyncTaskA(), asyncTaskB()).await See the join macro of futures[0]. The way it works is, it will create a future that, when polled, will call the underlying poll function of all three futures, saving the eventual result into a tuple. This will allow making progress on all three futures at the same time. [0] https://docs.rs/futures/0.3.0/futures/macr…

I don't like this at all. Having to rely on futures::join! means that I don't have the flexibility to control the execution of these things unless Rust adds that specific utility, right? In JS, for example, the `bluebird` library is a third party utility for managing execution of functions. You can do things like const results = await Promise.map(users, user => saveUserToDBAsync(user), { concurrency: 5}); And I pass…

The macro is just a wrapper around this (and a couple of other functions): https://docs.rs/futures/0.3.0/futures/future/fn.join.html

And from a quick scan of the source it doesn't look like anything there is impossible to implement in userspace: https://docs.rs/futures-util/0.3.0/src/futures_util/future/j...

Re: Async-await on stable Rust

#86
post #10

How does rust perform in parallel on the same memory? I heard it uses locks? This is not on the same memory right? https://news.ycombinator.com/item?id=21469295 If you want to do joint (on the same memory) parallel HTTP with Java I have a stable solution for you: https://github.com/tinspin/rupy

What do you mean by “on the same memory” exactly? If you want two threads running in parallel to concurrently access the same memory location you don't need synchronization if you only perform reads, and you need one if there is at least one write. Like in any other language (this comes directly from how CPU works). The good thing with Rust is that you can't shoot yourself in the foot: if you can't accidentally have…

I mean just like it reads: I want two (or more) threads to write the same memory at the same time. This is a problem Java "solved"/"worked around" with a complete memory model rewrite for the whole JDK and the concurrency package in 2004 (1.5).

The solutions range from mutexes to copy-on-write and more.

Re: Async-await on stable Rust

#87
post #79

Earlier quoted context omitted.

The join macro is also implemented “in user space”.

Thank you, so what is the syntax that is used in order to execute without awaiting? Do you create a thread for each?

This is where things get tricky: Rust didn't standardize an event loop - it only standardized common traits that allow implementing one, and a way to communicate whether a computation needs more time or already has a result.

If what you want to do is run multiple CPU-bound computation and have a central event loop awaiting the result, then yes, you'll need to spawn threads and use some kind of channel to transfer the state and result. If what you want is to run multiple IO-bound queries, then you'll want to use the facilities of the event loop of your choice (tokio, async-std, etc...) to register the intent that you're waiting for more data on a file-descriptor.

The "proper" way to execute without awaiting it on the current future is usually to spawn another future on the event loop. The syntax to do that with tokio is

    use tokio;
    let my_future = some_future();
    tokio::spawn(my_future);

Re: Async-await on stable Rust

#88

I’ve been playing with async await in a polar opposite vertical than its typical use case (high tps web backends) and believe this was the missing piece to further unlock great ergonomic and productivity gains for system development: embedded no_std. Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming wi…

related: async/await is also amazingly useful for game development. Stuff like writing an update loop, where `yield` is "wait until next frame to continue".

This can let you avoid a lot of the pomp and circumstance of writing state machines by hand.

Re: Async-await on stable Rust

#89
post #30

Isn't it kind of a poor design choice that Rust will not actually begin execution of the function until `.await` is called? If I didn't want to execute the function yet, I wouldn't have invoked it. Awaiting is a completely different concept than invoking, why overload it? If you want to defer execution of a promise until you await it, you can always do that, but this paradigm forces you to do that. The problem is the…

In rust, they separate the concept of a future from how it's actually run. Tokio is one way to run a bunch of futures, and it has many different options.

For instance, I use the CurrentThread runtime in tokio, because I'm using the rust code as a plugin to Postgres, and it accesses non-thread-safe APIs.

What you are asking for is essentially for the futures runtime to be hidden from you. That's fine for some languages that already have a big runtime and don't need the flexibility to do things differently, but doesn't work for rust.

Re: Async-await on stable Rust

#90
post #58

Earlier quoted context omitted.

Are you sure? How would the JavaScript functions execute simultaneously on a single thread? Async is about interleaving computations on a single thread.

Javascript has two differences that contribute here: * First, it runs the callee synchronously until the first await, which can fire off network requests, etc. * Second, continuations are pushed onto queues immediately- the microtask queue that runs when the current event handler returns, for example. Rust does neither of these things: * Calling an async function constructs its stack frame without running any of its…

> * Calling an async function constructs its stack frame without running any of its body.

This is actually possible to do by using async blocks instead of async functions. E.G. you can write this:

    fn test() -> impl Future {
        // Run some things directly here
        println!("I am running in the current frame");
        async {
            // Run some things in the await
            println!("I am running in the .await");
        }
    }
Post reply on HN