Skip to content

Commit

Permalink
Merge pull request #225 from nrc/intro
Browse files Browse the repository at this point in the history
New intro draft; shuffle contents around
  • Loading branch information
nrc authored Oct 9, 2024
2 parents 8591643 + 275e5be commit 5db5010
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 3 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
```
3 changes: 3 additions & 0 deletions ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ FutOne
FutTwo
FuturesUnordered
GenFuture
GitHub
gRPC
html
http
Expand Down Expand Up @@ -65,6 +66,7 @@ ReadIntoBuf
recognise
refactor
RefCell
repo
repurposed
requeue
ResponseFuture
Expand Down Expand Up @@ -102,6 +104,7 @@ Waker
waker
Wakeups
wakeups
webpage
webpages
webserver
Woot
2 changes: 2 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = [
"hello-world",
"01_02_why_async",
"01_04_async_await_primer",
"02_02_future_trait",
Expand All @@ -18,3 +19,4 @@ members = [
"09_04_concurrent_tcp_server",
"09_05_final_tcp_server",
]
resolver = "2"
8 changes: 8 additions & 0 deletions examples/hello-world/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hello-world"
version = "0.1.0"
authors = ["Nicholas Cameron <[email protected]>"]
edition = "2021"

[dependencies]
tokio = { version = "1.40.0", features = ["full"] }
10 changes: 10 additions & 0 deletions examples/hello-world/src/main.rs
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 14 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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)

53 changes: 53 additions & 0 deletions src/intro.md
Original file line number Diff line number Diff line change
@@ -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]().

0 comments on commit 5db5010

Please sign in to comment.