Expand description
Manage a group of tasks on a runtime.
Enables cancellation to be propagated across tasks, and ensures if an error occurs that all sibling tasks in the group are cancelled too.
§Closures and References
When calling group
, a GroupHandle
instance is passed into the closure.
The intended design is that the instance of GroupHandle
never outlives the
closure it’s contained within. This makes it so when the TaskGroup
exits
or is cancelled, it is also no longer possible to spawn more tasks on the
group.
However async closures are not yet a primitive in Rust, so we
cannot yet pass GroupHandle
by-reference. Instead we approximate the borrowing
behavior by requiring the GroupHandle
instance be returned at the end of
the closure.
§Credit
This codebase is based on the
task-group
project by Pat
Hickey.
§Examples
Create an echo tcp server which processes incoming connections in a loop without ever creating any dangling tasks:
use async_std::io;
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
async fn process(stream: TcpStream) -> io::Result<()> {
println!("Accepted from: {}", stream.peer_addr()?);
let mut reader = stream.clone();
let mut writer = stream;
io::copy(&mut reader, &mut writer).await?;
Ok(())
}
#[async_std::main]
async fn main() -> io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
println!("Listening on {}", listener.local_addr()?);
let handle = async_task_group::group(|group| async move {
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
let stream = stream?;
group.spawn(async move { process(stream).await });
}
Ok(group)
});
handle.await?;
Ok(())
}
Structs§
- Task builder that configures the settings of a new task
- A JoinHandle is used to manage a collection of tasks. There are two things you can do with it:
- A TaskGroup is used to spawn a collection of tasks. The collection has two properties:
Functions§
- Create a new instance.