Skip to content

Fix running code #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/01_getting_started/02_why_async.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ thread. In a typical threaded application, if you wanted to download two
different webpages at the same time, you would spread the work across two
different threads, like this:

```rust
```rust,ignore
{{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites}}
```

Expand All @@ -22,7 +22,7 @@ to eliminate. We can rewrite the function above using Rust's
`async`/`.await` notation, which will allow us to run multiple tasks at
once without creating multiple threads:

```rust
```rust,ignore
{{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites_async}}
```

Expand Down
18 changes: 9 additions & 9 deletions src/01_getting_started/04_async_await_primer.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ blocked `Future`s will yield control of the thread, allowing other

To create an asynchronous function, you can use the `async fn` syntax:

```rust
async fn do_something() { ... }
```rust,edition2018
async fn do_something() { /* ... */ }
```

The value returned by `async fn` is a `Future`. For anything to happen,
the `Future` needs to be run on an executor.

```rust
```rust,edition2018
{{#include ../../examples/01_04_async_await_primer/src/lib.rs:hello_world}}
```

Expand All @@ -29,16 +29,16 @@ other tasks to run if the future is currently unable to make progress.
For example, imagine that we have three `async fn`: `learn_song`, `sing_song`,
and `dance`:

```rust
async fn learn_song() -> Song { ... }
async fn sing_song(song: Song) { ... }
async fn dance() { ... }
```rust,ignore
async fn learn_song() -> Song { /* ... */ }
async fn sing_song(song: Song) { /* ... */ }
async fn dance() { /* ... */ }
```

One way to do learn, sing, and dance would be to block on each of these
individually:

```rust
```rust,ignore
{{#include ../../examples/01_04_async_await_primer/src/lib.rs:block_on_each}}
```

Expand All @@ -48,7 +48,7 @@ we can sing it, but it's possible to dance at the same time as learning and
singing the song. To do this, we can create two separate `async fn` which
can be run concurrently:

```rust
```rust,ignore
{{#include ../../examples/01_04_async_await_primer/src/lib.rs:block_on_main}}
```

Expand Down
10 changes: 5 additions & 5 deletions src/01_getting_started/05_http_server_example.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ Let's add some dependencies to the `Cargo.toml` file:
Now that we've got our dependencies out of the way, let's start writing some
code. We have some imports to add:

```rust
```rust,ignore
{{#include ../../examples/01_05_http_server/src/lib.rs:imports}}
```

Once the imports are out of the way, we can start putting together the
boilerplate to allow us to serve requests:

```rust
```rust,ignore
{{#include ../../examples/01_05_http_server/src/lib.rs:boilerplate}}
```

Expand All @@ -35,7 +35,7 @@ You can also inspect the request itself, which contains information such as
the request URI, HTTP version, headers, and other metadata. For example, we
can print out the URI of the request like this:

```rust
```rust,ignore
println!("Got request at {:?}", req.uri());
```

Expand All @@ -47,14 +47,14 @@ request to another website using Hyper's HTTP client.

We start by parsing out the URL we want to request:

```rust
```rust,ignore
{{#include ../../examples/01_05_http_server/src/lib.rs:parse_url}}
```

Then we can create a new `hyper::Client` and use it to make a `GET` request,
returning the response to the user:

```rust
```rust,ignore
{{#include ../../examples/01_05_http_server/src/lib.rs:get_request}}
```

Expand Down
10 changes: 5 additions & 5 deletions src/02_execution/02_future.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ must register `wake` to be called when data becomes ready on the socket,
which will tell the executor that our future is ready to make progress.
A simple `SocketRead` future might look something like this:

```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}}
```

Expand All @@ -39,15 +39,15 @@ operations without needing intermediate allocations. Running multiple futures
at once or chaining futures together can be implemented via allocation-free
state machines, like this:

```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:join}}
```

This shows how multiple futures can be run simultaneously without needing
separate allocations, allowing for more efficient asynchronous programs.
Similarly, multiple sequential futures can be run one after another, like this:

```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:and_then}}
```

Expand All @@ -56,12 +56,12 @@ control flow without requiring multiple allocated objects and deeply nested
callbacks. With the basic control-flow out of the way, let's talk about the
real `Future` trait and how it is different.

```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:real_future}}
```

The first change you'll notice is that our `self` type is no longer `&mut self`,
but has changed to `Pin<&mut Self>`. We'll talk more about pinning in [a later
but has changed to `Pin<&mut Self>`. We'll talk more about pinning in [a later
section][pinning], but for now know that it allows us to create futures that
are immovable. Immovable objects can store pointers between their fields,
e.g. `struct MyFut { a: i32, ptr_to_a: *const i32 }`. Pinning is necessary
Expand Down
6 changes: 3 additions & 3 deletions src/02_execution/03_wakeups.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ thread to communicate that the timer has elapsed and the future should complete.
We'll use a shared `Arc<Mutex<..>>` value to communicate between the thread and
the future.

```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:timer_decl}}
```

Now, let's actually write the `Future` implementation!

```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:future_for_timer}}
```

Expand All @@ -55,7 +55,7 @@ being polled.

Finally, we need the API to actually construct the timer and start the thread:

```rust
```rust,ignore
{{#include ../../examples/02_03_timer/src/lib.rs:timer_new}}
```

Expand Down
12 changes: 6 additions & 6 deletions src/02_execution/04_executor.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ futures-preview = "=0.3.0-alpha.17"

Next, we need the following imports at the top of `src/main.rs`:

```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:imports}}
```

Expand All @@ -47,7 +47,7 @@ Tasks themselves are just futures that can reschedule themselves, so we'll
store them as a future paired with a sender that the task can use to requeue
itself.

```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:executor_decl}}
```

Expand All @@ -56,7 +56,7 @@ This method will take a future type, box it and put it in a FutureObj,
and create a new `Arc<Task>` with it inside which can be enqueued onto the
executor.

```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:spawn_fn}}
```

Expand All @@ -70,23 +70,23 @@ the `waker_ref` or `.into_waker()` functions to turn an `Arc<impl ArcWake>`
into a `Waker`. Let's implement `ArcWake` for our tasks to allow them to be
turned into `Waker`s and awoken:

```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:arcwake_for_task}}
```

When a `Waker` is created from an `Arc<Task>`, calling `wake()` on it will
cause a copy of the `Arc` to be sent onto the task channel. Our executor then
needs to pick up the task and poll it. Let's implement that:

```rust
```rust,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:executor_run}}
```

Congratulations! We now have a working futures executor. We can even use it
to run `async/.await` code and custom futures, such as the `TimerFuture` we
wrote earlier:

```rust
```rust,edition2018,ignore
{{#include ../../examples/02_04_executor/src/lib.rs:main}}
```

Expand Down
14 changes: 7 additions & 7 deletions src/02_execution/05_io.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
In the previous section on [The `Future` Trait], we discussed this example of
a future that performed an asynchronous read on a socket:

```rust
```rust,ignore
{{#include ../../examples/02_02_future_trait/src/lib.rs:socket_read}}
```

Expand All @@ -26,9 +26,9 @@ a thread to block on multiple asynchronous IO events, returning once one of
the events completes. In practice, these APIs usually look something like
this:

```rust
```rust,ignore
struct IoBlocker {
...
/* ... */
}

struct Event {
Expand All @@ -41,7 +41,7 @@ struct Event {

impl IoBlocker {
/// Create a new collection of asynchronous IO events to block on.
fn new() -> Self { ... }
fn new() -> Self { /* ... */ }

/// Express an interest in a particular IO event.
fn add_io_event_interest(
Expand All @@ -54,10 +54,10 @@ impl IoBlocker {
/// which an event should be triggered, paired with
/// an ID to give to events that result from this interest.
event: Event,
) { ... }
) { /* ... */ }

/// Block until one of the events occurs.
fn block(&self) -> Event { ... }
fn block(&self) -> Event { /* ... */ }
}

let mut io_blocker = IoBlocker::new();
Expand All @@ -80,7 +80,7 @@ such as sockets that can configure callbacks to be run when a particular IO
event occurs. In the case of our `SocketRead` example above, the
`Socket::set_readable_callback` function might look like the following pseudocode:

```rust
```rust,ignore
impl Socket {
fn set_readable_callback(&self, waker: Waker) {
// `local_executor` is a reference to the local executor.
Expand Down
8 changes: 4 additions & 4 deletions src/03_async_await/01_chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ code to make progress while waiting on an operation to complete.
There are two main ways to use `async`: `async fn` and `async` blocks.
Each returns a value that implements the `Future` trait:

```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:async_fn_and_block_examples}}
```

Expand All @@ -29,7 +29,7 @@ Unlike traditional functions, `async fn`s which take references or other
non-`'static` arguments return a `Future` which is bounded by the lifetime of
the arguments:

```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:lifetimes_expanded}}
```

Expand All @@ -43,7 +43,7 @@ One common workaround for turning an `async fn` with references-as-arguments
into a `'static` future is to bundle the arguments with the call to the
`async fn` inside an `async` block:

```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:static_future_with_borrow}}
```

Expand All @@ -57,7 +57,7 @@ closures. An `async move` block will take ownership of the variables it
references, allowing it to outlive the current scope, but giving up the ability
to share those variables with other code:

```rust
```rust,edition2018,ignore
{{#include ../../examples/03_01_async_await/src/lib.rs:async_move_examples}}
```

Expand Down
22 changes: 11 additions & 11 deletions src/04_pinning/01_chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Pinning makes it possible to guarantee that an object won't ever be moved.
To understand why this is necessary, we need to remember how `async`/`.await`
works. Consider the following code:

```rust
let fut_one = ...;
let fut_two = ...;
```rust,edition2018,ignore
let fut_one = /* ... */;
let fut_two = /* ... */;
async move {
fut_one.await;
fut_two.await;
Expand All @@ -24,7 +24,7 @@ async move {
Under the hood, this creates an anonymous type that implements `Future`,
providing a `poll` method that looks something like this:

```rust
```rust,ignore
// The `Future` type generated by our `async { ... }` block
struct AsyncFuture {
fut_one: FutOne,
Expand Down Expand Up @@ -69,7 +69,7 @@ is able to successfully complete.
However, what happens if we have an `async` block that uses references?
For example:

```rust
```rust,edition2018,ignore
async {
let mut x = [0; 128];
let read_into_buf_fut = read_into_buf(&mut x);
Expand All @@ -80,7 +80,7 @@ async {

What struct does this compile down to?

```rust
```rust,ignore
struct ReadIntoBuf<'a> {
buf: &'a mut [u8], // points to `x` below
}
Expand Down Expand Up @@ -118,22 +118,22 @@ used as futures, and both implement `Unpin`.

For example:

```rust
```rust,edition2018,ignore
use pin_utils::pin_mut; // `pin_utils` is a handy crate available on crates.io

// A function which takes a `Future` that implements `Unpin`.
fn execute_unpin_future(x: impl Future<Output = ()> + Unpin) { ... }
fn execute_unpin_future(x: impl Future<Output = ()> + Unpin) { /* ... */ }

let fut = async { ... };
let fut = async { /* ... */ };
execute_unpin_future(fut); // Error: `fut` does not implement `Unpin` trait

// Pinning with `Box`:
let fut = async { ... };
let fut = async { /* ... */ };
let fut = Box::pin(fut);
execute_unpin_future(fut); // OK

// Pinning with `pin_mut!`:
let fut = async { ... };
let fut = async { /* ... */ };
pin_mut!(fut);
execute_unpin_future(fut); // OK
```
Expand Down
Loading