Skip to content

Commit

Permalink
update original
Browse files Browse the repository at this point in the history
  • Loading branch information
funkill committed Nov 15, 2024
1 parent 05accae commit 51f661f
Show file tree
Hide file tree
Showing 23 changed files with 900 additions and 7 deletions.
1 change: 1 addition & 0 deletions async-book/ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ proxying
pseudocode
ReadIntoBuf
recognise
repo
refactor
RefCell
repo
Expand Down
3 changes: 3 additions & 0 deletions async-book/examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[workspace]
members = [
"hello-world",
"hello-world-sleep",
"hello-world-spawn",
"hello-world-join",
"01_02_why_async",
"01_04_async_await_primer",
"02_02_future_trait",
Expand Down
8 changes: 8 additions & 0 deletions async-book/examples/hello-world-join/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hello-world-join"
version = "0.1.0"
authors = ["Nicholas Cameron <[email protected]>"]
edition = "2021"

[dependencies]
tokio = { version = "1.40.0", features = ["full"] }
23 changes: 23 additions & 0 deletions async-book/examples/hello-world-join/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use tokio::{spawn, time::{sleep, Duration}};

async fn say_hello() {
// Wait for a while before printing to make it a more interesting race.
sleep(Duration::from_millis(100)).await;
println!("hello");
}

async fn say_world() {
sleep(Duration::from_millis(100)).await;
println!("world");
}

#[tokio::main]
async fn main() {
let handle1 = spawn(say_hello());
let handle2 = spawn(say_world());

let _ = handle1.await;
let _ = handle2.await;

println!("!");
}
8 changes: 8 additions & 0 deletions async-book/examples/hello-world-sleep/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hello-world-sleep"
version = "0.1.0"
authors = ["Nicholas Cameron <[email protected]>"]
edition = "2021"

[dependencies]
tokio = { version = "1.40.0", features = ["full"] }
20 changes: 20 additions & 0 deletions async-book/examples/hello-world-sleep/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::io::{stdout, Write};
use tokio::time::{sleep, Duration};

async fn say_hello() {
print!("hello, ");
// Flush stdout so we see the effect of the above `print` immediately.
stdout().flush().unwrap();
}

async fn say_world() {
println!("world!");
}

#[tokio::main]
async fn main() {
say_hello().await;
// An async sleep function, puts the current task to sleep for 1s.
sleep(Duration::from_millis(1000)).await;
say_world().await;
}
8 changes: 8 additions & 0 deletions async-book/examples/hello-world-spawn/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hello-world-spawn"
version = "0.1.0"
authors = ["Nicholas Cameron <[email protected]>"]
edition = "2021"

[dependencies]
tokio = { version = "1.40.0", features = ["full"] }
20 changes: 20 additions & 0 deletions async-book/examples/hello-world-spawn/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use tokio::{spawn, time::{sleep, Duration}};

async fn say_hello() {
// Wait for a while before printing to make it a more interesting race.
sleep(Duration::from_millis(100)).await;
println!("hello");
}

async fn say_world() {
sleep(Duration::from_millis(100)).await;
println!("world!");
}

#[tokio::main]
async fn main() {
spawn(say_hello());
spawn(say_world());
// Wait for a while to give the tasks time to run.
sleep(Duration::from_millis(1000)).await;
}
29 changes: 29 additions & 0 deletions async-book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,37 @@

# Part 1: guide

- [Introduction](part-guide/intro.md)
- [Concurrent programming](part-guide/concurrency.md)
- [Async and await](part-guide/async-await.md)
- [Advanced async/await topics](part-guide/adv-async-await.md)
- [IO and issues with blocking](part-guide/io.md)
- [Concurrency primitives](part-guide/concurrency-primitives.md)
- [Channels, locking, and synchronization](part-guide/sync.md)
- [Tools for async programming](part-guide/tools.md)
- [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)
- [Async iterators (streams)](part-guide/streams.md)

# Part 2: reference

- [Implementing futures and streams]()
- [Alternate runtimes]()
- [Implementing your own runtime]()
- [async in sync, sync in async]()
- [Async IO: readiness vs completion, and io_uring]()
- [Design patterns]()
- [Cancellation]() (cancellation safety)
- [Starvation]()
- [Pinning]()
- [Async and FFI]()
- [Comparing async programming in Rust to other languages]()
- [The implementation of async/await in rustc]()
- structured concurrency?


# Old chapters

- [Getting Started](01_getting_started/01_chapter.md)
Expand Down
12 changes: 5 additions & 7 deletions async-book/src/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ NOTE: this guide is currently undergoing a rewrite after a long time without muc

This book is a guide to asynchronous programming in Rust. It is designed to help you take your first steps and to discover more about advanced topics. We don't assume any experience with asynchronous programming (in Rust or another language), but we do assume you're familiar with Rust already. If you want to learn about Rust, you could start with [The Rust Programming Language](https://doc.rust-lang.org/stable/book/).

This book has two main parts: part one is a beginners guide, it is designed to be read in-order and to take you from total beginner to intermediate level. Part two is a collection of stand-alone chapters on more advanced topics. It should be useful once you've worked through part one or if you already have some experience with async Rust.
This book has two main parts: [part one](part-guide/intro.md) is a beginners guide, it is designed to be read in-order and to take you from total beginner to intermediate level. Part two is a collection of stand-alone chapters on more advanced topics. It should be useful once you've worked through part one or if you already have some experience with async Rust.

You can navigate this book in multiple ways:

* You can read it front to back, in order. This is the recommend path for newcomers to async Rust, at least for part one of the book.
* You can read it front to back, in order. This is the recommend path for newcomers to async Rust, at least for [part one](part-guide/intro.md) of the book.
* There is a summary contents on the left-hand side of the webpage.
* If you want information about a broad topic, you could start with the topic index.
* If you want to find all discussion about a specific topic, you could start with the detailed index.
* You could see if your question is answered in the FAQs.


## What is Async Programming?
## What is Async Programming and why would you do it?

In concurrent programming, the program does multiple things at the same time (or at least appears to). Programming with threads is one form of concurrent programming. Code within a thread is written in sequential style and the operating system executes threads concurrently. With async programming, concurrency happens entirely within your program (the operating system is not involved). An async runtime (which is just another crate in Rust) manages async tasks in conjunction with the programmer explicitly yielding control by using the `await` keyword.

Because the operating system is not involved, *context switching* in the async world is very fast. Furthermore, async tasks have much lower memory overhead than operating system threads. This makes async programming a good fit for systems which need to handle very many concurrent tasks and where those tasks spend a lot of time waiting (for example, for client responses or for IO).

Async programming also offers the programmer fine-grained control over how tasks are executed (levels of parallelism and concurrency, control flow, scheduling, and so forth). This means that async programming can be expressive as well as ergonomic for many uses.
Async programming also offers the programmer fine-grained control over how tasks are executed (levels of parallelism and concurrency, control flow, scheduling, and so forth). This means that async programming can be expressive as well as ergonomic for many uses. In particular, async programming in Rust has a powerful concept of cancellation and supports many different flavours of concurrency (expressed using constructs including `spawn` and it's variations, `join`, `select`, `for_each_concurrent`, etc.). These allow composable and reusable implementations of concepts like timeouts, pausing, and throttling.


## Hello, world!
Expand All @@ -34,9 +34,7 @@ Just to give you a taste of what async Rust looks like, here is a 'hello, world'

We'll explain everything in detail later. For now, note how we define an asynchronous function using `async fn` and call it using `.await` - an async function in Rust doesn't do anything unless it is `await`ed[^blocking].

Like all examples in this book, if you want to see the full example (including `Cargo.toml`, for example) or to run it yourself locally, you can find them in the book's GitHub repo: e.g., [examples/hello-world]().

TODO link: https://github.com/rust-lang/async-book/tree/master/examples/hello-world
Like all examples in this book, if you want to see the full example (including `Cargo.toml`, for example) or to run it yourself locally, you can find them in the book's GitHub repo: e.g., [examples/hello-world](https://github.com/rust-lang/async-book/tree/master/examples/hello-world).


## Development of Async Rust
Expand Down
65 changes: 65 additions & 0 deletions async-book/src/part-guide/adv-async-await.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# More async/await topics

## Unit tests

## Blocking and cancellation

- Two important concepts to be aware of early, we'll revisit in more detail as we go along
- Cancellation
- How to do it
- drop a future
- cancellation token
- abort functions
- Why it matters, cancellation safety (forward ref)
- Blocking
- IO and computation can block
- why it's bad
- how to deal is a forward ref to io chapter

## `Send + 'static` bounds on futures

- Why they're there, multi-threaded runtimes
- spawn local to avoid them
- What makes an async fn `Send + 'static` and how to fix bugs with it

## Async traits

- syntax
- The `Send + 'static` issue and working around it
- trait_variant
- explicit future
- return type notation (https://blog.rust-lang.org/inside-rust/2024/09/26/rtn-call-for-testing.html)
- overriding
- future vs async notation for methods
- object safety
- capture rules (https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html)
- history and async-trait crate


## Async blocks and closures

- async block syntax
- what it means
- using an async block in a function returning a future
- subtype of async method
- closures
- coming soon (https://github.com/rust-lang/rust/pull/132706, https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html)
- async blocks in closures vs async closures
- errors in async blocks
- https://rust-lang.github.io/async-book/07_workarounds/02_err_in_async_blocks.html

## Recursion

- Allowed (relatively new), but requires some explicit boxing
- forward reference to futures, pinning
- https://rust-lang.github.io/async-book/07_workarounds/04_recursion.html
- https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html#support-for-recursion-in-async-fn
- async-recursion macro (https://docs.rs/async-recursion/latest/async_recursion/)


## Lifetimes and borrowing

- Mentioned the static lifetime above
- Lifetime bounds on futures (`Future + '_`, etc.)
- Borrowing across await points
- I don't know, I'm sure there are more lifetime issues with async functions ...
Loading

0 comments on commit 51f661f

Please sign in to comment.