Skip to content

Commit ff83c82

Browse files
committed
beginning of an Async section
1 parent cdada28 commit ff83c82

File tree

5 files changed

+121
-0
lines changed

5 files changed

+121
-0
lines changed

src/SUMMARY.md

+15
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,21 @@
225225
- [With Java](android/interoperability/java.md)
226226
- [Exercises](exercises/day-4/android.md)
227227

228+
# Day 4: Afternoon (Async)
229+
230+
----
231+
232+
- [Async](async.md)
233+
- [async/await](async/async-await.md)
234+
- [Async Blocks](async/async-blocks.md)
235+
- Futures
236+
- Executors
237+
- Polling
238+
- Pin
239+
- Channels
240+
- Select
241+
- [Exercises](exercises/day-4/async.md)
242+
228243
# Final Words
229244

230245
- [Thanks!](thanks.md)

src/async.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Async Rust
2+
3+
"Async" is a concurrency model where multiple tasks are executed concurrently by
4+
executing each task until it would block, then switching to another task that is
5+
ready to make progress. The model scales to higher concurrency than threads
6+
because the per-task overhead is typically very low and operating systems
7+
provide means of efficiently selecting tasks that can make progress.
8+
9+
## Comparisons
10+
11+
* Python has a similar model in its `asyncio`. However, its `Future` type is
12+
callback-based, and not polled. Async Python programs require a "loop",
13+
similar to an executor in Rust.
14+
15+
* JavaScript's `Promise` is similar, but again callback-based. The language
16+
runtime implements the event loop, so many of the details of Promise
17+
resolution are hidden.

src/async/async-await.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# `async`/`await`
2+
3+
At a high level, async Rust code looks very much like "normal" sequential code:
4+
5+
```rust,editable
6+
use tokio::time;
7+
8+
async fn count_to(i: i32) {
9+
for i in 1..10 {
10+
println!("Count in task: {i}!");
11+
time::sleep(time::Duration::from_millis(5)).await;
12+
}
13+
}
14+
15+
#[tokio::main]
16+
async fn main() {
17+
tokio::spawn(count_to(10));
18+
19+
for i in 1..5 {
20+
println!("Main task: {i}");
21+
time::sleep(time::Duration::from_millis(5)).await;
22+
}
23+
}
24+
```
25+
26+
<details>
27+
28+
Key points:
29+
30+
* Tokio is one of several async runtimes available for Rust.
31+
32+
* The function is decorated with the "async" keyword to indicate that it is async. The
33+
`tokio::main` macro invocation is a convenience to wrap the `main` function as a task.
34+
35+
* The `spawn` function creates a new, concurrent "task", just like spawning a thread.
36+
37+
* Whenever a task would block, we add an `.await` which returns control to the runtime until the
38+
blocking operation is ready to proceed.
39+
40+
Further exploration:
41+
42+
* Why does `count_to` not (usually) get to 10? This is an example of async cancellation.
43+
`tokio::spawn` returns a handle which can be awaited to wait until it finishes.
44+
45+
* Try `count_to(10).await` instead of spawning.
46+
47+
* Try importing `tokio::join` and using it to join multiple handles.
48+
49+
Note that the Rust playground does not allow network connections, so examples like making HTTP
50+
requests are not possible.
51+
52+
</details>

src/async/async-blocks.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Async Blocks
2+
3+
Similar to closures, a snippet of async code can be included inline in another
4+
function with an async block:
5+
6+
```rust, editable
7+
use tokio::{time, task};
8+
9+
#[tokio::main]
10+
async fn main() {
11+
let mut joinset = task::JoinSet::new();
12+
13+
for i in 1..5 {
14+
joinset.spawn(async move {
15+
println!("task {i} starting");
16+
time::sleep(time::Duration::from_millis(i)).await;
17+
println!("task {i} done");
18+
format!("hello from task {i}")
19+
});
20+
}
21+
22+
while let Some(res) = joinset.join_next().await {
23+
let greeting = res.unwrap();
24+
println!("task joined with result: {greeting}");
25+
}
26+
}
27+
28+
<details>
29+
30+
An async block is similar to a closure, but does not take any arguments.
31+
32+
Its return value is a Future, which is described on the next slide.
33+
34+
</details>

src/exercises/day-4/async.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Exercises
2+
3+
TBD

0 commit comments

Comments
 (0)