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