From e23b5dea5aa55830f065e123a6d6fbcd514a37c5 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 15 Nov 2024 14:38:53 +1300 Subject: [PATCH] Fix CI, skip spell check Signed-off-by: Nick Cameron --- .github/workflows/ci.yml | 2 -- src/SUMMARY.md | 4 ++-- src/part-guide/async-await.md | 10 +++++----- src/part-guide/intro.md | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba453b0a..c9a682af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,12 +14,10 @@ jobs: - uses: actions/checkout@v2 - name: Install Rust run: rustup update stable && rustup default stable - - run: sudo apt-get update && sudo apt-get install aspell aspell-en - name: Install mdbook uses: taiki-e/install-action@mdbook - name: Install mdbook-linkcheck uses: taiki-e/install-action@mdbook-linkcheck - - run: bash ci/spellcheck.sh list - run: mdbook build - run: cargo test --all --manifest-path=./examples/Cargo.toml --target-dir ./target - uses: rust-lang/simpleinfra/github-actions/static-websites@master diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ffc06ec0..ecbab002 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -20,7 +20,7 @@ - [Destruction and clean-up](part-guide/dtors.md) - [Futures](part-guide/futures.md) - [Runtimes](part-guide/runtimes.md) -- [Timers and signal handling](part-guide/times-signals.md) +- [Timers and signal handling](part-guide/timers-signals.md) - [Async iterators (streams)](part-guide/streams.md) # Part 2: reference @@ -37,7 +37,7 @@ - [Async and FFI]() - [Comparing async programming in Rust to other languages]() - [The implementation of async/await in rustc]() -- structured concurrency? +- [Structured concurrency?]() # Old chapters diff --git a/src/part-guide/async-await.md b/src/part-guide/async-await.md index a6622078..96e1bc5a 100644 --- a/src/part-guide/async-await.md +++ b/src/part-guide/async-await.md @@ -111,7 +111,7 @@ Finally, for one more perspective on `await`: we mentioned earlier that futures Let's start by revisiting our 'hello, world!' example: ```rust,edition2021 -{{#include ../examples/hello-world/src/main.rs}} +{{#include ../../examples/hello-world/src/main.rs}} ``` You should now recognise the boilerplate around `main`. It's for initializing the Tokio runtime and creating an initial task to run the async `main` function. @@ -143,7 +143,7 @@ The code is a bit more interesting, but we're essentially doing the same thing - For all the talk so far about concurrency, parallelism, and asynchrony, both these examples are 100% sequential. Just calling and awaiting async functions does not introduce any concurrency unless there are other tasks to schedule while the awaiting task is waiting. To prove this to ourselves, lets look at another simple (but contrived) example: ```rust,edition2021 -{{#include ../examples/hello-world-sleep/src/main.rs}} +{{#include ../../examples/hello-world-sleep/src/main.rs}} ``` Between printing "hello" and "world", we put the current task to sleep[^async-sleep] for one second. Observe what happens when we run the program: it prints "hello", does nothing for one second, then prints "world". That is because executing a single task is purely sequential. If we had some concurrency, then that one second nap would be an excellent opportunity to get some other work done, like printing "world". We'll see how to do that in the next section. @@ -158,7 +158,7 @@ We've talked about async and await as a way to run code in an async task. And we Here's a tiny example of running an async function on a separate task by using `spawn`: ```rust,edition2021 -{{#include ../examples/hello-world-spawn/src/main.rs}} +{{#include ../../examples/hello-world-spawn/src/main.rs}} ``` Similar to the last example, we have two functions printing "hello" and "world!". But this time we run them concurrently (and in parallel) rather than sequentially. If you run the program a few times you should see the strings printing in both orders - sometimes "hello" first, sometimes "world!" first. A classic concurrent race! @@ -184,7 +184,7 @@ For example, let's revisit our 'Hello, world!' example one more time: ```rust,edition2021 -{{#include ../examples/hello-world-join/src/main.rs}} +{{#include ../../examples/hello-world-join/src/main.rs}} ``` The code is similar to last time, but instead of just calling `spawn`, we save the returned `JoinHandle`s and later `await` them. Since we're waiting for those tasks to complete before we exit the `main` function, we no longer need the `sleep` in `main`. @@ -197,4 +197,4 @@ If we immediately `await`ed the `JoinHandle` of the first `spawn` rather than sa 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`. -`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](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. +`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. diff --git a/src/part-guide/intro.md b/src/part-guide/intro.md index 66cbec39..6295bdf9 100644 --- a/src/part-guide/intro.md +++ b/src/part-guide/intro.md @@ -1,5 +1,5 @@ # Part 1: A guide to asynchronous programming in Rust -This part of the book is a tutorial-style guide to async Rust. It is aimed at newcomers to async programming in Rust. It should be useful whether or not you've done async programming in other languages. If you have, you might skip the first section or skim it as a refresher. You might also want to read this [comparison to async in other languages](TODO) sooner rather than later. +This part of the book is a tutorial-style guide to async Rust. It is aimed at newcomers to async programming in Rust. It should be useful whether or not you've done async programming in other languages. If you have, you might skip the first section or skim it as a refresher. You might also want to read this [comparison to async in other languages]() sooner rather than later. We'll start by discussing different models of [concurrent programming](concurrency.md), using processes, threads, or async tasks. This chapter will cover the essential parts of Rust's async model before we get into the nitty-gritty of programming in the second chapter where we introduce the async and await syntax.