Skip to content

Commit dc1a476

Browse files
committed
add "async await on stable rust!" blog post
1 parent c6c2200 commit dc1a476

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
layout: post
3+
title: "Async-await on stable Rust!"
4+
author: Niko Matsakis
5+
---
6+
7+
**On this coming Thursday, November 7, async-await syntax hits stable
8+
Rust, as part of the 1.39.0 release.** This work has been a long time
9+
in development -- the key ideas for zero-cost futures, for example,
10+
were [first proposed by Aaron Turon and Alex Crichton in
11+
2016][zcf-rust]! -- and we are very proud of the end result! We
12+
believe that Async I/O -- and async-await in particular -- is going to
13+
be an increasingly important part of Rust's story.
14+
15+
While this first release of "async-await" is a momentous event, it's
16+
also only the beginning. The current support for async-await marks a
17+
kind of "Minimum Viable Product" (MVP), and we expect to be polishing,
18+
improving, and extending it for some time.
19+
20+
Already, in the time since [async-await hit beta][aa-beta], we've made
21+
a lot of great progress -- including making some [key diagnostic
22+
improvements][diag] that help to make async-await errors **far** more
23+
approachable. If you'd like to get involved in that work, check out
24+
the [Async Foundations Working Group][wg] -- if nothing else, you can
25+
help us by filing bugs about polish issues or by [nominating those bugs
26+
that are bothering you the most][nom], to help direct our efforts.
27+
28+
# Major developments in the async ecosystem
29+
30+
Now that async-await is approaching stabilization, all the major Async
31+
I/O runtimes are busily at work adding and extending their support for
32+
the new syntax:
33+
34+
* the [tokio] runtime [recently announced a number of scheduler
35+
improvements][tokio-sched], and they are planning a stable release
36+
in November that supports async-await syntax;
37+
* the [async-std] runtime [has been putting out weekly releases for the past months][as-releases], and plans to make their
38+
1.0 release shortly after async-await hits stable;
39+
* using [wasm-bindgen-futures], you can even bridge Rust Futures with
40+
[JavaScript promises];
41+
* the [hyper library][hyper] has [migrated][hyper#1805] to adopt standard Rust futures;
42+
* the 0.3.0 version of the [futures-rs library][futures] will support
43+
async-await and will be released at or around the time async-await hits stable
44+
(you can use the [0.3.0-alpha][] releases now);
45+
* finally, async-await support is starting to become available in higher-level
46+
[web frameworks][wf] as well.
47+
48+
[futures]: https://crates.io/crates/futures-preview
49+
[tokio]: https://tokio.rs/
50+
[zcf-rust]: https://aturon.github.io/blog/2016/08/11/futures/
51+
[wasm-bindgen-futures]: https://docs.rs/crate/wasm-bindgen-futures/0.2.16
52+
[aa-beta]: https://blog.rust-lang.org/2019/09/30/Async-await-hits-beta.html
53+
[diag]: https://blog.rust-lang.org/inside-rust/2019/10/11/AsyncAwait-Not-Send-Error-Improvements.html
54+
[wg]: https://rust-lang.github.io/compiler-team/working-groups/async-await/
55+
[nom]: https://rust-lang.github.io/compiler-team/working-groups/async-await/#nominating-issues
56+
[tokio-sched]: https://tokio.rs/blog/2019-10-scheduler/
57+
[as-releases]: https://github.com/async-rs/async-std/releases
58+
[0.3.0-alpha]: https://rust-lang-nursery.github.io/futures-rs/blog/2018/07/19/futures-0.3.0-alpha.1.html
59+
[hyper]: https://hyper.rs
60+
[hyper#1805]: https://github.com/hyperium/hyper/issues/1805
61+
[async-std]: https://async.rs/
62+
[wf]: https://www.arewewebyet.org/topics/frameworks/
63+
64+
### Async await: a quick primer
65+
66+
*(This section and the next are reproduced from the ["Async-await hits
67+
beta!"][aa-beta] post.)*
68+
69+
So, what is async await? Async-await is a way to write functions that
70+
can "pause", return control to the runtime, and then pick up from
71+
where they left off. Typically those pauses are to wait for I/O, but
72+
there can be any number of uses.
73+
74+
You may be familiar with the async-await from other languages, such as
75+
JavaScript or C#. Rust's version of the feature is similar, but with a
76+
few key differences.
77+
78+
To use async-await, you start by writing `async fn` instead of `fn`:
79+
80+
```rust
81+
async fn first_function() -> u32 { .. }
82+
```
83+
84+
Unlike a regular function, calling an `async fn` doesn't do anything
85+
to start -- instead, it returns a `Future`. This is a suspended
86+
computation that is waiting to be executed. To actually *execute*
87+
the future, you have to use the `.await` operator:
88+
89+
```rust
90+
async fn another_function() {
91+
// Create the future:
92+
let future = first_function();
93+
94+
// Await the future, which will execute it (and suspend
95+
// this function if we encounter a need to wait for I/O):
96+
let result: u32 = future.await;
97+
...
98+
}
99+
```
100+
101+
This example shows the first difference between Rust and other
102+
languages: we write `future.await` instead of `await future`. This
103+
syntax integrates better with Rust's `?` operator for propagating
104+
errors (which, after all, are very common in I/O). One can simply
105+
write `future.await?` to await the result of a future and propagate
106+
errors. It also has the advantage of making method chaining painless.
107+
108+
### Zero-cost futures
109+
110+
The other difference between Rust futures and futures in other
111+
languages is that they are based on a "poll" model, which makes them
112+
**zero cost**. In other languages, invoking an async function
113+
immediately creates a future and schedules it for execution: awaiting
114+
the future isn't really necessary for it to execute. But this implies
115+
some overhead for each future that is created.
116+
117+
In contrast, in Rust, calling an async function does not do any
118+
scheduling in and of itself, which means that we can compose a complex
119+
nest of futures without incurring a per-future cost. As an end-user,
120+
though, the main thing you'll notice is that **futures feel "lazy"**:
121+
they don't do anything until you await them.
122+
123+
If you'd like a closer look at how futures work under the hood, take a
124+
look at [the executor section] of the [async book], or watch the
125+
[excellent talk][video] that [withoutboats] gave at [Rust LATAM 2019]
126+
on the topic.
127+
128+
[the executor section]: https://rust-lang.github.io/async-book/02_execution/04_executor.html
129+
[video]: https://www.youtube.com/watch?v=skos4B5x7qE
130+
[Rust LATAM 2019]: https://rustlatam.org/
131+
[withoutboats]: https://github.com/withoutboats
132+
[async book]: https://github.com/rust-lang/async-book
133+
134+
### Summary
135+
136+
We believe that having async-await on stable Rust is going to be a key
137+
enabler for a lot of new and exciting developments in Rust. If you've
138+
tried Async I/O in Rust in the past and had problems -- particularly
139+
if you tried the combinator-based futures of the past -- you'll find
140+
[async-await integrates much better with Rust's borrowing
141+
system][bc]). Moreover, there are a now a number of great runtimes and
142+
other libraries available in the ecosystem to work with. So get out
143+
there and build stuff!
144+
145+
[bc]: http://aturon.github.io/tech/2018/04/24/async-borrowing/

0 commit comments

Comments
 (0)