Skip to content

Commit

Permalink
Ch. 17 §02: correct numbering and content for Listings 17-13 and 17-14
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskrycho committed Jun 13, 2024
1 parent 4604302 commit 9053e9b
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 122 deletions.
33 changes: 0 additions & 33 deletions listings/ch17-async-await/listing-17-06-orig/src/main.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use std::time::Duration;
use std::{
future::Future,
pin::{pin, Pin},
time::Duration,
};

fn main() {
trpl::block_on(async {
let (tx, mut rx) = trpl::channel();

let tx_fut = async {
let tx1 = tx.clone();
let tx1_fut = pin!(async move {
let vals = vec![
String::from("hi"),
String::from("from"),
Expand All @@ -13,19 +18,18 @@ fn main() {
];

for val in vals {
tx.send(val).unwrap();
tx1.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
};
});

let rx_fut = async {
while let Some(received) = rx.recv().await {
println!("Got: {received}");
let rx_fut = pin!(async {
while let Some(value) = rx.recv().await {
println!("received '{value}'");
}
};
});

// ANCHOR: updated
let tx_fut2 = async {
let tx_fut = pin!(async move {
let vals = vec![
String::from("more"),
String::from("messages"),
Expand All @@ -37,9 +41,13 @@ fn main() {
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
};
});

// ANCHOR: here
let futures: Vec<Pin<Box<dyn Future<Output = ()>>>> =
vec![Box::pin(tx1_fut), Box::pin(rx_fut), Box::pin(tx_fut)];
// ANCHOR_END: here

trpl::join3(tx_fut, tx_fut2, rx_fut).await;
// ANCHOR_END: updated
trpl::join_all(futures).await;
});
}
42 changes: 11 additions & 31 deletions listings/ch17-async-await/listing-17-13/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
use std::{
future::Future,
pin::{pin, Pin},
time::Duration,
};
use std::time::Duration;

fn main() {
trpl::block_on(async {
let (tx, mut rx) = trpl::channel();

let tx1 = tx.clone();
let tx1_fut = pin!(async move {
// ANCHOR: futures
let tx_fut = async {
let vals = vec![
String::from("hi"),
String::from("from"),
Expand All @@ -18,36 +14,20 @@ fn main() {
];

for val in vals {
tx1.send(val).unwrap();
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
});
};

let rx_fut = pin!(async {
let rx_fut = async {
// ANCHOR: loop
while let Some(value) = rx.recv().await {
println!("received '{value}'");
}
});

let tx_fut = pin!(async move {
let vals = vec![
String::from("more"),
String::from("messages"),
String::from("for"),
String::from("you"),
];

for val in vals {
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
});

// ANCHOR: here
let futures: Vec<Pin<Box<dyn Future<Output = ()>>>> =
vec![Box::pin(tx1_fut), Box::pin(rx_fut), Box::pin(tx_fut)];
// ANCHOR_END: here
// ANCHOR_END: loop
};

trpl::join_all(futures).await;
trpl::join(tx_fut, rx_fut).await;
// ANCHOR_END: futures
});
}
66 changes: 66 additions & 0 deletions listings/ch17-async-await/listing-17-14-orig/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::{
future::Future,
pin::{pin, Pin},
time::Duration,
};

fn main() {
trpl::block_on(async {
let (tx, mut rx) = trpl::channel();

let tx1 = tx.clone();
// ANCHOR: here
let tx1_fut = pin!(async move {
// snip...
// ANCHOR_END: here
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("future"),
];

for val in vals {
tx1.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
// ANCHOR: here
});
// ANCHOR_END: here

// ANCHOR: here
let rx_fut = pin!(async {
// snip...
// ANCHOR_END: here
while let Some(value) = rx.recv().await {
println!("received '{value}'");
}
// ANCHOR: here
});
// ANCHOR_END: here

// ANCHOR: here
let tx_fut = pin!(async move {
// snip...
// ANCHOR_END: here
let vals = vec![
String::from("more"),
String::from("messages"),
String::from("for"),
String::from("you"),
];

for val in vals {
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
// ANCHOR: here
});

let futures: Vec<Pin<&mut dyn Future<Output = ()>>> =
vec![tx1_fut, rx_fut, tx_fut];
// ANCHOR_END: here

trpl::join_all(futures).await;
});
}
47 changes: 13 additions & 34 deletions listings/ch17-async-await/listing-17-14/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
use std::{
future::Future,
pin::{pin, Pin},
time::Duration,
};
use std::time::Duration;

fn main() {
trpl::block_on(async {
let (tx, mut rx) = trpl::channel();

let tx1 = tx.clone();
// ANCHOR: here
let tx1_fut = pin!(async move {
// snip...
// ANCHOR_END: here
let tx_fut = async {
let vals = vec![
String::from("hi"),
String::from("from"),
Expand All @@ -21,28 +13,19 @@ fn main() {
];

for val in vals {
tx1.send(val).unwrap();
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
// ANCHOR: here
});
// ANCHOR_END: here
};

// ANCHOR: here
let rx_fut = pin!(async {
// snip...
// ANCHOR_END: here
while let Some(value) = rx.recv().await {
println!("received '{value}'");
let rx_fut = async {
while let Some(received) = rx.recv().await {
println!("Got: {received}");
}
// ANCHOR: here
});
// ANCHOR_END: here
};

// ANCHOR: here
let tx_fut = pin!(async move {
// snip...
// ANCHOR_END: here
// ANCHOR: updated
let tx_fut2 = async {
let vals = vec![
String::from("more"),
String::from("messages"),
Expand All @@ -54,13 +37,9 @@ fn main() {
tx.send(val).unwrap();
trpl::sleep(Duration::from_secs(1)).await;
}
// ANCHOR: here
});

let futures: Vec<Pin<&mut dyn Future<Output = ()>>> =
vec![tx1_fut, rx_fut, tx_fut];
// ANCHOR_END: here
};

trpl::join_all(futures).await;
trpl::join3(tx_fut, tx_fut2, rx_fut).await;
// ANCHOR_END: updated
});
}
19 changes: 10 additions & 9 deletions src/ch17-02-concurrency-with-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,12 @@ receiving each message, rather than before receiving any message, we need to
give put the `tx` and `rx` operations in their own async blocks, so the runtime
can execute each of them separately. We also need to tell the runtime to
actually run them using `trpl::join`, just like we did for the counting example
above. Listing 17-TODO shows how that looks.
above. Listing 17-13 shows how that looks.

<Listing number="17-TODO" caption="Separating `send` and `recv` into their own `async` blocks and awaiting the futures for those blocks" file-name="src/main.rs">
<Listing number="17-13" caption="Separating `send` and `recv` into their own `async` blocks and awaiting the futures for those blocks" file-name="src/main.rs">

```rust
{{#rustdoc_include ../listings/ch17-async-await/listing-17-06-orig/src/main.rs:futures}}
{{#rustdoc_include ../listings/ch17-async-await/listing-17-13/src/main.rs:futures}}
```

</Listing>
Expand Down Expand Up @@ -333,10 +333,10 @@ Right now, the async block only borrows `tx`. We can confirm this by adding
another async block which uses `tx`, and using `trpl::join3` to wait for all
three futures to complete:

<Listing number="17-TODO" caption="Adding another async block which borrows `tx`, to see that we can borrow it repeatedly" file-name="src/main.rs">
<Listing number="17-14" caption="Adding another async block which borrows `tx`, to see that we can borrow it repeatedly" file-name="src/main.rs">

```rust
{{#rustdoc_include ../listings/ch17-async-await/listing-17-07-orig/src/main.rs:updated}}
{{#rustdoc_include ../listings/ch17-async-await/listing-17-14/src/main.rs:updated}}
```

</Listing>
Expand All @@ -346,6 +346,8 @@ which `rx` can then receive. When we run that code, we see the extra output from
the new `async` block, and the message it sends being received by the
`rx.recv()`.

<!-- TODO: extract to output? -->

```text
Got: hi
Got: more
Expand All @@ -358,10 +360,9 @@ Got: you
```

As before, we also see that the program does not shut down on its own and
requires a <span class="keystroke">ctrl-c</span>, though. This little
exploration helps us understand why: it is ultimately about *ownership*. We need
to move `tx` into the async block so that once that block ends, `tx` will be
dropped.
requires a <span class="keystroke">ctrl-c</span>. This little exploration helps
us understand why: it is ultimately about *ownership*. We need to move `tx` into
the async block so that once that block ends, `tx` will be dropped.

Since we have seen how `async` blocks borrow the items they reference from their
outer scope, we can go ahead and remove the extra block we just added for now,
Expand Down
4 changes: 2 additions & 2 deletions src/ch17-03-more-futures.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ for exactly this. Putting that together, we end up with the code in Listing
<Listing number="17-TODO" caption="Using `Pin` and `Box::pin` to make the `Vec` type check" file-name="src/main.rs">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch17-async-await/listing-17-13/src/main.rs:here}}
{{#rustdoc_include ../listings/ch17-async-await/listing-17-13-orig/src/main.rs:here}}
```

</Listing>
Expand Down Expand Up @@ -410,7 +410,7 @@ dynamic `Future` type.
<Listing number="17-TODO" caption="Using `Pin` directly with the `pin!` macro to avoid unnecessary heap allocations" file-name="src/main.rs">

```rust
{{#rustdoc_include ../listings/ch17-async-await/listing-17-14/src/main.rs:here}}
{{#rustdoc_include ../listings/ch17-async-await/listing-17-14-orig/src/main.rs:here}}
```

</Listing>
Expand Down

0 comments on commit 9053e9b

Please sign in to comment.