Skip to content

Commit 1309235

Browse files
committed
Merge "Async-await on stable Rust!" blog post
2 parents 410c955 + edf57a1 commit 1309235

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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 believe
12+
that Async I/O is going to be an increasingly important part of Rust's
13+
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). 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. 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
26+
bugs that are bothering you the most][nom], to help direct our
27+
efforts.
28+
29+
Many thanks are due to the people who made async-await a reality. The
30+
implementation and design would never have happened without the
31+
leadership of cramertj and withoutboats, the implementation and polish
32+
work from the compiler side (davidtwco, tmandry, gilescope, csmoe),
33+
the core generator support that futures builds on (Zoxc), the
34+
foundational work on `Future` and the `Pin` APIs (aturon,
35+
alexcrichton, RalfJ, pythonesque), and of course the input provided by
36+
so many community members on RFC threads and discussions.
37+
38+
# Major developments in the async ecosystem
39+
40+
Now that async-await is approaching stabilization, all the major Async
41+
I/O runtimes are at work adding and extending their support for the
42+
new syntax:
43+
44+
* the [tokio] runtime [recently announced a number of scheduler
45+
improvements][tokio-sched], and they are planning a stable release
46+
in November that supports async-await syntax;
47+
* the [async-std] runtime [has been putting out weekly releases for the past few months][as-releases], and plans to make their
48+
1.0 release shortly after async-await hits stable;
49+
* using [wasm-bindgen-futures], you can even bridge Rust Futures with
50+
[JavaScript promises];
51+
* the [hyper library][hyper] has [migrated][hyper#1805] to adopt standard Rust futures;
52+
* the newly released 0.3.0 version of the [futures-rs library][futures] includes support
53+
for async-await;
54+
* finally, async-await support is starting to become available in higher-level
55+
[web frameworks][wf] as well, as well as other interesting applications such
56+
as the [`futures_intrusive`](https://docs.rs/futures-intrusive/0.2.0/futures_intrusive/)
57+
crate.
58+
59+
[futures]: https://crates.io/crates/futures-preview
60+
[tokio]: https://tokio.rs/
61+
[zcf-rust]: https://aturon.github.io/blog/2016/08/11/futures/
62+
[wasm-bindgen-futures]: https://docs.rs/crate/wasm-bindgen-futures/0.2.16
63+
[aa-beta]: https://blog.rust-lang.org/2019/09/30/Async-await-hits-beta.html
64+
[diag]: https://blog.rust-lang.org/inside-rust/2019/10/11/AsyncAwait-Not-Send-Error-Improvements.html
65+
[wg]: https://rust-lang.github.io/compiler-team/working-groups/async-await/
66+
[nom]: https://rust-lang.github.io/compiler-team/working-groups/async-await/#nominating-issues
67+
[tokio-sched]: https://tokio.rs/blog/2019-10-scheduler/
68+
[as-releases]: https://github.com/async-rs/async-std/releases
69+
[0.3.0-alpha]: https://rust-lang-nursery.github.io/futures-rs/blog/2018/07/19/futures-0.3.0-alpha.1.html
70+
[hyper]: https://hyper.rs
71+
[hyper#1805]: https://github.com/hyperium/hyper/issues/1805
72+
[async-std]: https://async.rs/
73+
[wf]: https://www.arewewebyet.org/topics/frameworks/
74+
75+
### Async-await: a quick primer
76+
77+
*(This section and the next are reproduced from the ["Async-await hits
78+
beta!"][aa-beta] post.)*
79+
80+
So, what is async await? Async-await is a way to write functions that
81+
can "pause", return control to the runtime, and then pick up from
82+
where they left off. Typically those pauses are to wait for I/O, but
83+
there can be any number of uses.
84+
85+
You may be familiar with the async-await from other languages, such as
86+
JavaScript or C#. Rust's version of the feature is similar, but with a
87+
few key differences.
88+
89+
To use async-await, you start by writing `async fn` instead of `fn`:
90+
91+
```rust
92+
async fn first_function() -> u32 { .. }
93+
```
94+
95+
Unlike a regular function, calling an `async fn` doesn't have any
96+
immediate effect. Instead, it returns a `Future`. This is a suspended
97+
computation that is waiting to be executed. To actually *execute* the
98+
future, use the `.await` operator:
99+
100+
```rust
101+
async fn another_function() {
102+
// Create the future:
103+
let future = first_function();
104+
105+
// Await the future, which will execute it (and suspend
106+
// this function if we encounter a need to wait for I/O):
107+
let result: u32 = future.await;
108+
...
109+
}
110+
```
111+
112+
This example shows the first difference between Rust and other
113+
languages: we write `future.await` instead of `await future`. This
114+
syntax integrates better with Rust's `?` operator for propagating
115+
errors (which, after all, are very common in I/O). You can simply
116+
write `future.await?` to await the result of a future and propagate
117+
errors. It also has the advantage of making method chaining painless.
118+
119+
### Zero-cost futures
120+
121+
The other difference between Rust futures and futures in other
122+
languages is that they are based on a "poll" model, which makes them
123+
**zero cost**. In other languages, invoking an async function
124+
immediately creates a future and schedules it for execution: awaiting
125+
the future isn't necessary for it to execute. But this implies some
126+
overhead for each future that is created.
127+
128+
In contrast, in Rust, calling an async function does not do any
129+
scheduling in and of itself, which means that we can compose a complex
130+
nest of futures without incurring a per-future cost. As an end-user,
131+
though, the main thing you'll notice is that **futures feel "lazy"**:
132+
they don't do anything until you await them.
133+
134+
If you'd like a closer look at how futures work under the hood, take a
135+
look at [the executor section] of the [async book], or watch the
136+
[excellent talk][video] that [withoutboats] gave at [Rust LATAM 2019]
137+
on the topic.
138+
139+
[the executor section]: https://rust-lang.github.io/async-book/02_execution/04_executor.html
140+
[video]: https://www.youtube.com/watch?v=skos4B5x7qE
141+
[Rust LATAM 2019]: https://rustlatam.org/
142+
[withoutboats]: https://github.com/withoutboats
143+
[async book]: https://github.com/rust-lang/async-book
144+
145+
### Summary
146+
147+
We believe that having async-await on stable Rust is going to be a key
148+
enabler for a lot of new and exciting developments in Rust. If you've
149+
tried Async I/O in Rust in the past and had problems -- particularly
150+
if you tried the combinator-based futures of the past -- you'll find
151+
[async-await integrates much better with Rust's borrowing
152+
system][bc]. Moreover, there are now a number of great runtimes and
153+
other libraries available in the ecosystem to work with. So get out
154+
there and build stuff!
155+
156+
[bc]: http://aturon.github.io/tech/2018/04/24/async-borrowing/

0 commit comments

Comments
 (0)