Tarefas
Rust tem um sistema de tarefas, que é uma forma de threading leve.
Uma tarefa tem uma única future de nível superior que o executor polls para fazer progresso. Essa future pode ter uma ou mais futures aninhadas que seu método poll polls, correspondendo vagamente a uma pilha de chamadas. A concorrência dentro de uma tarefa é possível polling várias futures filhas, como correr um temporizador e uma operação de I/O.
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
println!("escutando na porta {}", listener.local_addr()?.port());
loop {
let (mut socket, addr) = listener.accept().await?;
println!("conexão de {addr:?}");
tokio::spawn(async move {
socket.write_all(b"Quem é você?\n").await.expect("erro de _socket_");
let mut buf = vec![0; 1024];
let name_size = socket.read(&mut buf).await.expect("erro de _socket_");
let name = std::str::from_utf8(&buf[..name_size]).unwrap().trim();
let reply = format!("Obrigado por ligar, {name}!\n");
socket.write_all(reply.as_bytes()).await.expect("erro de _socket_");
});
}
}
Copie este exemplo para o seu src/main.rs preparado e execute-o a partir daí.
Tente se conectar a ele com uma ferramenta de conexão TCP como nc ou telnet.
-
Pergunte aos alunos para visualizar qual seria o estado do servidor de exemplo com alguns clientes conectados. Quais tarefas existem? Quais são suas futures?
-
Esta é a primeira vez que vemos um bloco
async. Isso é semelhante a um closure, mas não aceita argumentos. Seu valor de retorno é uma future, semelhante a umasync fn. -
Refatore o bloco async em uma função e melhore o tratamento de erros usando
?.