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
?
.