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 um async fn.

  • Refatore o bloco async em uma função e melhore o tratamento de erros usando ?.