Skip to content

Commit 3908609

Browse files
authored
Merge pull request #252 from nrc/conc-prim
Concurrent composition and structured concurrency chapters
2 parents ef2837b + acb85d7 commit 3908609

File tree

11 files changed

+414
-24
lines changed

11 files changed

+414
-24
lines changed

src/SUMMARY.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- [Async and await](part-guide/async-await.md)
1515
- [More async/await topics](part-guide/more-async-await.md)
1616
- [IO and issues with blocking](part-guide/io.md)
17-
- [Concurrency primitives](part-guide/concurrency-primitives.md)
17+
- [Composing futures concurrently](part-guide/concurrency-primitives.md)
1818
- [Channels, locking, and synchronization](part-guide/sync.md)
1919
- [Tools for async programming](part-guide/tools.md)
2020
- [Destruction and clean-up](part-guide/dtors.md)
@@ -31,13 +31,13 @@
3131
- [async in sync, sync in async]()
3232
- [Async IO: readiness vs completion, and io_uring]()
3333
- [Design patterns]()
34-
- [Cancellation]() (cancellation safety)
34+
- [Cancellation and cancellation safety](part-reference/cancellation.md) (cancellation safety)
3535
- [Starvation]()
3636
- [Pinning]()
3737
- [Async and FFI]()
3838
- [Comparing async programming in Rust to other languages]()
3939
- [The implementation of async/await in rustc]()
40-
- [Structured concurrency?]()
40+
- [Structured concurrency](part-reference/structured.md)
4141

4242

4343
# Old chapters

src/navigation/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
- [Cancellation](../part-guide/more-async-await.md#cancellation)
2121
- [`CancellationToken`](../part-guide/more-async-await.md#cancellation)
22+
- [In `select`](../part-guide/concurrency-primitives.md#race-select)
2223
- [Concurrency](../part-guide/concurrency.md)
2324
- [c.f., parallelism](../part-guide/concurrency.md#concurrency-and-parallelism)
25+
- [Primitives (`join`, `select`, etc.)](../part-guide/concurrency-primitives.md)
2426

2527

2628

@@ -38,6 +40,7 @@
3840

3941

4042

43+
- [`join`](../part-guide/concurrency-primitives.md#join)
4144
- [Joining tasks](../part-guide/async-await.md#joining-tasks)
4245
- [`JoinHandle`](../part-guide/async-await.md#joinhandle)
4346
- [`abort`](../part-guide/more-async-await.md#cancellation)
@@ -55,12 +58,14 @@
5558

5659

5760

61+
- [`race`](../part-guide/concurrency-primitives.md#race-select)
5862
- [Reactor](../part-guide/async-await.md#the-runtime)
5963
- [Runtimes](../part-guide/async-await.md#the-runtime)
6064

6165

6266

6367
- [Scheduler](../part-guide/async-await.md#the-runtime)
68+
- [`select`](../part-guide/concurrency-primitives.md#race-select)
6469
- [Spawning tasks](../part-guide/async-await.md#spawning-tasks)
6570

6671

@@ -74,3 +79,4 @@
7479
- Traits
7580
- [async](../part-guide/more-async-await.md#async-traits)
7681
- `Future`
82+
[`try_join`](../part-guide/concurrency-primitives.md#join)

src/navigation/topics.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@
44

55
- [Introduction](../part-guide/concurrency.md#concurrency-and-parallelism)
66
- [Running async tasks in parallel using `spawn`](../part-guide/async-await.md#spawning-tasks)
7+
- [Running futures concurrently using `join` and `select`](../part-guide/concurrency-primitives.md)
8+
79

810
## Correctness and safety
911

1012
- Cancellation
1113
- [Introduction](../part-guide/more-async-await.md#cancellation)
14+
- [In `select` and `try_join`](../part-guide/concurrency-primitives.md)
15+
1216

1317
## Performance
1418

1519
- Blocking
1620
- [Introduction](../part-guide/more-async-await.md#blocking-and-cancellation)
1721

22+
1823
## Testing
1924

2025
- [Unit test syntax](../part-guide/more-async-await.md#unit-tests)

src/part-guide/async-await.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ That's it! You're ready to write some asynchronous code!
4040

4141
The `#[tokio::main]` annotation initializes the Tokio runtime and starts an async task for running the code in `main`. Later in this guide we'll explain in more detail what that annotation is doing and how to use async code without it (which will give you more flexibility).
4242

43+
### Futures-rs and the ecosystem
44+
45+
TODO context and history, what futures-rs is for - was used a lot, probably don't need it now, overlap with Tokio and other runtimes (sometimes with subtle semantic differences), why you might need it (working with futures directly, esp writing your own, streams, some utils)
46+
47+
Other ecosystem stuff - Yosh's crates, alt runtimes, experimental stuff, other?
4348

4449
### Futures and tasks
4550

@@ -197,4 +202,4 @@ If we immediately `await`ed the `JoinHandle` of the first `spawn` rather than sa
197202

198203
We'll quickly look at `JoinHandle` in a little more depth. The fact that we can `await` a `JoinHandle` is a clue that a `JoinHandle` is itself a future. `spawn` is not an `async` function, it's a regular function that returns a future (`JoinHandle`). It does some work (to schedule the task) before returning the future (unlike an async future), which is why we don't *need* to `await` `spawn`. Awaiting a `JoinHandle` waits for the spawned task to complete and then returns the result. In the above example, there was no result, we just waited for the task to complete. `JoinHandle` is a generic type and it's type parameter is the type returned by the spawned task. In the above example, the type would be `JoinHandle<()>`, a future that results in a `String` would produce a `JoinHandle` with type `JoinHandle<String>`.
199204

200-
`await`ing a `JoinHandle` returns a `Result` (which is why we used `let _ = ...` in the above example, it avoids a warning about an unused `Result`). If the spawned task completed successfully, then the task's result will be in the `Ok` variant. If the task panicked or was aborted (a form of cancellation, see [TODO]()), then the result will be an `Err` containing a [`JoinError` docs](https://docs.rs/tokio/latest/tokio/task/struct.JoinError.html). If you are not using cancellation via `abort` in your project, then `unwrapping` the result of `JoinHandle.await` is a reasonable approach, since that is effectively propagating a panic from the spawned task to the spawning task.
205+
`await`ing a `JoinHandle` returns a `Result` (which is why we used `let _ = ...` in the above example, it avoids a warning about an unused `Result`). If the spawned task completed successfully, then the task's result will be in the `Ok` variant. If the task panicked or was aborted (a form of [cancellation](../part-reference/cancellation.md)), then the result will be an `Err` containing a [`JoinError` docs](https://docs.rs/tokio/latest/tokio/task/struct.JoinError.html). If you are not using cancellation via `abort` in your project, then `unwrapping` the result of `JoinHandle.await` is a reasonable approach, since that is effectively propagating a panic from the spawned task to the spawning task.

0 commit comments

Comments
 (0)