From 275e5be1b010ec52d0deaeade6811685b028721a Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 8 Oct 2024 17:03:52 +1300 Subject: [PATCH] New intro draft; shuffle contents around Signed-off-by: Nick Cameron --- README.md | 14 +++++++-- ci/dictionary.txt | 3 ++ examples/Cargo.toml | 2 ++ examples/hello-world/Cargo.toml | 8 +++++ examples/hello-world/src/main.rs | 10 ++++++ src/SUMMARY.md | 14 +++++++++ src/intro.md | 53 ++++++++++++++++++++++++++++++++ 7 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 examples/hello-world/Cargo.toml create mode 100644 examples/hello-world/src/main.rs create mode 100644 src/intro.md diff --git a/README.md b/README.md index aa8276be..9e065814 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ -# async-book -Asynchronous Programming in Rust +# Asynchronous Programming in Rust + +This book aims to be a thorough guide to asynchronous programming in Rust, from beginner to advanced. + +This book has been unmaintained for a long time and has not had a lot of love. We're currently working to bring it up to date and make it much better! As we're making some major changes, the content might be a bit mixed up, parts may be duplicated or missing, etc. Bear with us, it'll get better soon :-) To see what we're planning and to let us know what you think, see [issue 224](https://github.com/rust-lang/async-book/issues/224). ## Requirements -The async book is built with [`mdbook`], you can install it using cargo. + +The async book is built with [`mdbook`] ([docs](https://rust-lang.github.io/mdBook/index.html)), you can install it using cargo. ``` cargo install mdbook @@ -12,14 +16,18 @@ cargo install mdbook-linkcheck [`mdbook`]: https://github.com/rust-lang/mdBook ## Building + To create a finished book, run `mdbook build` to generate it under the `book/` directory. + ``` mdbook build ``` ## Development + While writing it can be handy to see your changes, `mdbook serve` will launch a local web server to serve the book. + ``` mdbook serve ``` diff --git a/ci/dictionary.txt b/ci/dictionary.txt index 5c0fe901..eacbf455 100644 --- a/ci/dictionary.txt +++ b/ci/dictionary.txt @@ -26,6 +26,7 @@ FutOne FutTwo FuturesUnordered GenFuture +GitHub gRPC html http @@ -65,6 +66,7 @@ ReadIntoBuf recognise refactor RefCell +repo repurposed requeue ResponseFuture @@ -102,6 +104,7 @@ Waker waker Wakeups wakeups +webpage webpages webserver Woot diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 99566a77..d995d8ad 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ + "hello-world", "01_02_why_async", "01_04_async_await_primer", "02_02_future_trait", @@ -18,3 +19,4 @@ members = [ "09_04_concurrent_tcp_server", "09_05_final_tcp_server", ] +resolver = "2" diff --git a/examples/hello-world/Cargo.toml b/examples/hello-world/Cargo.toml new file mode 100644 index 00000000..c58488b2 --- /dev/null +++ b/examples/hello-world/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello-world" +version = "0.1.0" +authors = ["Nicholas Cameron "] +edition = "2021" + +[dependencies] +tokio = { version = "1.40.0", features = ["full"] } diff --git a/examples/hello-world/src/main.rs b/examples/hello-world/src/main.rs new file mode 100644 index 00000000..8334c0f2 --- /dev/null +++ b/examples/hello-world/src/main.rs @@ -0,0 +1,10 @@ +// Define an async function. +async fn say_hello() { + println!("hello, world!"); +} + +#[tokio::main] // Boilerplate which lets us write `async fn main`, we'll explain it later. +async fn main() { + // Call an async function and await its result. + say_hello().await; +} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 122fe1e2..922a8597 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -1,5 +1,18 @@ # Table of Contents +[Introduction](intro.md) + +- [Navigation]() + - [By topic]() + - [FAQs]() + - [Index]() + +# Part 1: guide + +# Part 2: reference + +# Old chapters + - [Getting Started](01_getting_started/01_chapter.md) - [Why Async?](01_getting_started/02_why_async.md) - [The State of Asynchronous Rust](01_getting_started/03_state_of_async_rust.md) @@ -35,3 +48,4 @@ - [TODO: Modeling Servers and the Request/Response Pattern]() - [TODO: Managing Shared State]() - [Appendix: Translations of the Book](12_appendix/01_translations.md) + diff --git a/src/intro.md b/src/intro.md new file mode 100644 index 00000000..675e81ae --- /dev/null +++ b/src/intro.md @@ -0,0 +1,53 @@ +NOTE: this guide is currently undergoing a rewrite after a long time without much work. It is work in progress, much is missing, and what exists is a bit rough. + +# Introduction + +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. + +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. +* 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? + +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. + + +## Hello, world! + +Just to give you a taste of what async Rust looks like, here is a 'hello, world' example. There is no concurrency, and it doesn't really take advantage of being async. It does define and use an async function, and it does print "hello, world!": + +```rust,edition2021 +{{#include ../examples/hello-world/src/main.rs}} +``` + +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 + + +## Development of Async Rust + +The async features of Rust have been in development for a while, but it is not a 'finished' part of the language. Async Rust (at least the parts available in the stable compiler and standard libraries) is reliable and performant. It is used in production in some of the most demanding situations at the largest tech companies. However, there are some missing parts and rough edges (rough in the sense of ergonomics rather than reliability). You are likely to stumble upon some of these parts during your journey with async Rust. For most missing parts, there are workarounds and these are covered in this book. + +Currently, working with async iterators (also known as streams) is where most users find some rough parts. Some uses of async in traits are not yet well-supported. Async closures don't exist yet, and there is not a good solution for async destruction. + +Async Rust is being actively worked on. If you want to follow development, you can check out the Async Working Group's [home page](https://rust-lang.github.io/wg-async/meetings.html) which includes their [roadmap](https://rust-lang.github.io/wg-async/vision/roadmap.html). Or you could read the async [project goal](https://github.com/rust-lang/rust-project-goals/issues/105) within the Rust Project. + +Rust is an open source project. If you'd like to contribute to development of async Rust, start at the [contributing docs](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md) in the main Rust repo. + + +[^blocking]: This is actually a bad example because `println` is *blocking IO* and it is generally a bad idea to do blocking IO in async functions. We'll explain what blocking IO is in [chapter TODO]() and why you shouldn't do blocking IO in an async function in [chapter TODO]().