Skip to content

Commit 1ef20c7

Browse files
authored
Merge pull request #191 from Nereuxofficial/spawning
Added Spawning example
2 parents cdb9148 + 04e8b6c commit 1ef20c7

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

ci/dictionary.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ AsyncRead
99
AsyncWrite
1010
AwaitingFutOne
1111
AwaitingFutTwo
12+
cancelling
1213
combinator
1314
combinators
1415
compat
@@ -37,6 +38,7 @@ interprocess
3738
IoBlocker
3839
IOCP
3940
IoObject
41+
JoinHandle
4042
kqueue
4143
localhost
4244
LocalExecutor

examples/06_04_spawning/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "example_06_04_spawning"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
futures = "0.3"
10+
11+
[dependencies.async-std]
12+
version = "1.12.0"
13+
features = ["attributes"]

examples/06_04_spawning/src/lib.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#![cfg(test)]
2+
#![allow(dead_code)]
3+
4+
// ANCHOR: example
5+
use async_std::{task, net::TcpListener, net::TcpStream};
6+
use futures::AsyncWriteExt;
7+
8+
async fn process_request(stream: &mut TcpStream) -> Result<(), std::io::Error>{
9+
stream.write_all(b"HTTP/1.1 200 OK\r\n\r\n").await?;
10+
stream.write_all(b"Hello World").await?;
11+
Ok(())
12+
}
13+
14+
async fn main() {
15+
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
16+
loop {
17+
// Accept a new connection
18+
let (mut stream, _) = listener.accept().await.unwrap();
19+
// Now process this request without blocking the main loop
20+
task::spawn(async move {process_request(&mut stream).await});
21+
}
22+
}
23+
// ANCHOR_END: example
24+
use std::time::Duration;
25+
async fn my_task(time: Duration) {
26+
println!("Hello from my_task with time {:?}", time);
27+
task::sleep(time).await;
28+
println!("Goodbye from my_task with time {:?}", time);
29+
}
30+
// ANCHOR: join_all
31+
use futures::future::join_all;
32+
async fn task_spawner(){
33+
let tasks = vec![
34+
task::spawn(my_task(Duration::from_secs(1))),
35+
task::spawn(my_task(Duration::from_secs(2))),
36+
task::spawn(my_task(Duration::from_secs(3))),
37+
];
38+
// If we do not await these tasks and the function finishes, they will be dropped
39+
join_all(tasks).await;
40+
}
41+
// ANCHOR_END: join_all
42+
43+
#[test]
44+
fn run_task_spawner() {
45+
futures::executor::block_on(task_spawner());
46+
}

examples/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ members = [
1010
"05_02_iteration_and_concurrency",
1111
"06_02_join",
1212
"06_03_select",
13+
"06_04_spawning",
1314
"07_05_recursion",
1415
"09_01_sync_tcp_server",
1516
"09_02_async_tcp_server",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# `Spawning`
2+
3+
Spawning allows you to run a new asynchronous task in the background. This allows us to continue executing other code
4+
while it runs.
5+
6+
Say we have a web server that wants to accept connections without blocking the main thread.
7+
To achieve this, we can use the `async_std::task::spawn` function to create and run a new task that handles the
8+
connections. This function takes a future and returns a `JoinHandle`, which can be used to wait for the result of the
9+
task once it's completed.
10+
11+
```rust,edition2018
12+
{{#include ../../examples/06_04_spawning/src/lib.rs:example}}
13+
```
14+
15+
The `JoinHandle` returned by `spawn` implements the `Future` trait, so we can `.await` it to get the result of the task.
16+
This will block the current task until the spawned task completes. If the task is not awaited, your program will
17+
continue executing without waiting for the task, cancelling it if the function is completed before the task is finished.
18+
19+
```rust,edition2018
20+
{{#include ../../examples/06_04_spawning/src/lib.rs:join_all}}
21+
```
22+
23+
To communicate between the main task and the spawned task, we can use channels
24+
provided by the async runtime used.

src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
- [Executing Multiple Futures at a Time](06_multiple_futures/01_chapter.md)
1717
- [`join!`](06_multiple_futures/02_join.md)
1818
- [`select!`](06_multiple_futures/03_select.md)
19-
- [TODO: Spawning]()
19+
- [Spawning](06_multiple_futures/04_spawning.md)
2020
- [TODO: Cancellation and Timeouts]()
2121
- [TODO: `FuturesUnordered`]()
2222
- [Workarounds to Know and Love](07_workarounds/01_chapter.md)

0 commit comments

Comments
 (0)