<h2>O que é Tokio e Por Que Usar?</h2>
<p>Tokio é um runtime assíncrono de alta performance para Rust, construído sobre a abstração de futures e async/await. Diferentemente de runtimes bloqueantes tradicionais, Tokio permite que múltiplas tarefas sejam executadas concorrentemente em um número reduzido de threads, maximizando a utilização de recursos. É a escolha padrão para aplicações web, sistemas distribuídos e qualquer cenário onde latência e throughput são críticos.</p>
<p>O grande diferencial do Tokio é sua capacidade de gerenciar milhares de conexões simultâneas sem criar uma thread por conexão. Você escreve código que parece síncrono, mas executa de forma assíncrona sob o capô, usando <code>.await</code> para pausar execução quando operações I/O são necessárias.</p>
<pre><code class="language-rust">use tokio::task;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let handle = task::spawn(async {
sleep(Duration::from_secs(2)).await;
println!("Tarefa completada!");
});
handle.await.unwrap();
}</code></pre>
<h2>Arquitetura e Componentes Fundamentais</h2>
<h3>Work-Stealing Scheduler</h3>
<p>Tokio utiliza um scheduler baseado em work-stealing, onde múltiplas worker threads roubam trabalho uma da outra quando ficam ociosas. Isso distribui carga de forma eficiente sem overhead de sincronização excessiva. Por padrão, Tokio cria uma thread por núcleo de CPU, mas isso é configurável.</p>
<h3>Task Spawning e Concorrência</h3>
<p>Tasks são unidades de trabalho leves que podem ser spawned para execução concorrente. Diferente de threads do SO, tasks têm overhead mínimo. Use <code>tokio::spawn</code> para criar novas tasks ou <code>tokio::task::block_in_place</code> quando precisar executar código síncrono.</p>
<pre><code class="language-rust">use tokio::task;
#[tokio::main]
async fn main() {
let mut handles = vec![];
for i in 0..5 {
let handle = task::spawn(async move {
println!("Task {}", i);
i * 2
});
handles.push(handle);
}
for handle in handles {
let resultado = handle.await.unwrap();
println!("Resultado: {}", resultado);
}
}</code></pre>
<h2>Padrões Práticos: Sync, Select e Timeouts</h2>
<h3>Synchronization com Canais</h3>
<p>Tokio fornece <code>mpsc</code> (multi-producer, single-consumer) para comunicação entre tasks. Use canais quando multiple tasks precisam enviar dados para um consumer central.</p>
<pre><code class="language-rust">use tokio::sync::mpsc;
#[tokio::main]
async fn main() {
let (tx, mut rx) = mpsc::channel(100);
tokio::spawn(async move {
for i in 0..5 {
tx.send(i).await.unwrap();
}
});
while let Some(valor) = rx.recv().await {
println!("Recebido: {}", valor);
}
}</code></pre>
<h3>Select para Múltiplas Operações</h3>
<p>O macro <code>tokio::select!</code> permite aguardar múltiplas futures simultaneamente, respondendo ao primeiro resultado. Essencial para timeouts, graceful shutdown e multiplexação.</p>
<pre><code class="language-rust">use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let mut counter = 0;
loop {
tokio::select! {
_ = sleep(Duration::from_secs(1)) => {
counter += 1;
println!("Tick {}", counter);
if counter >= 3 { break; }
}
}
}
}</code></pre>
<h3>Timeouts Robustos</h3>
<p>Sempre use timeouts em operações I/O para evitar deadlocks infinitos. <code>tokio::time::timeout</code> encapsula uma future com limite de tempo.</p>
<pre><code class="language-rust">use tokio::time::{timeout, Duration};
#[tokio::main]
async fn main() {
let resultado = timeout(
Duration::from_secs(2),
sua_operacao_demorada()
).await;
match resultado {
Ok(Ok(value)) => println!("Sucesso: {}", value),
Ok(Err(e)) => println!("Erro na operação: {}", e),
Err(_) => println!("Timeout!"),
}
}
async fn sua_operacao_demorada() -> Result<String, String> {
Ok("dados".to_string())
}</code></pre>
<h2>Aplicação Real: Servidor HTTP Assíncrono</h2>
<p>Combinando conhecimento anterior, vamos construir um servidor que demonstra os padrões aprendidos. Aqui usamos <code>hyper</code> (que roda sobre Tokio) para aceitar requisições, processar tasks paralelas e responder com timeout.</p>
<pre><code class="language-rust">use hyper::{Body, Request, Response, Server, StatusCode};
use std::convert::Infallible;
use tokio::time::{timeout, Duration};
async fn handle_request(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
let resultado = timeout(Duration::from_secs(5), processar_requisicao()).await;
let resposta = match resultado {
Ok(Ok(data)) => Response::new(Body::from(data)),
Ok(Err(_)) => Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Erro no processamento"))
.unwrap(),
Err(_) => Response::builder()
.status(StatusCode::GATEWAY_TIMEOUT)
.body(Body::from("Timeout"))
.unwrap(),
};
Ok(resposta)
}
async fn processar_requisicao() -> Result<String, Box<dyn std::error::Error>> {
tokio::time::sleep(Duration::from_millis(100)).await;
Ok("OK".to_string())
}
#[tokio::main]
async fn main() {
let addr = ([127, 0, 0, 1], 3000).into();
let server = Server::bind(&addr)
.serve(hyper::service::make_service_fn(|_conn| async {
Ok::<_, Infallible>(hyper::service::service_fn(handle_request))
}));
println!("Servidor rodando em {}", addr);
server.await.unwrap();
}</code></pre>
<h2>Conclusão</h2>
<p>Tokio é essencial para Rust moderno em produção. Os três pontos-chave para dominar: <strong>primeiro</strong>, entenda que <code>.await</code> não bloqueia threads, apenas pausar a execução da task individual; <strong>segundo</strong>, sempre use timeouts em I/O para sistemas robusto; <strong>terceiro</strong>, leverage work-stealing scheduler spawning muitas tasks leves em vez de poucas threads pesadas. Começar com exemplos simples e evoluir para padrões como canais e select é o caminho mais seguro para proficiência.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://tokio.rs" target="_blank" rel="noopener noreferrer">Tokio Official Documentation</a></li>
<li><a href="https://rust-lang.github.io/async-book/" target="_blank" rel="noopener noreferrer">The Async Book - Rust</a></li>
<li><a href="https://tokio.rs/tokio/tutorial" target="_blank" rel="noopener noreferrer">Tokio Tutorial by Example</a></li>
<li><a href="https://hyper.rs" target="_blank" rel="noopener noreferrer">Hyper HTTP Client/Server</a></li>
<li><a href="https://doc.rust-lang.org/book/ch20-00-final-project-a-web-server.html" target="_blank" rel="noopener noreferrer">Programming in Rust: The Official Book - Chapter 20</a></li>
</ul>