---
title: "Rust nos Workers: exemplos para rodar no seu Worker"
description: "Como rodar Rust nativo — e até Tokio — dentro de um Worker com o alvo Emscripten: os três exemplos oficiais, o que muda no modelo de thread e os limites da prévia."
url: "https://www.escoladeaplicativos.com.br/arsenal/rust-workers-guia-exemplos"
author: "Mauro Mequelussi"
---

# Rust nos Workers: exemplos para rodar no seu Worker

> Como rodar Rust nativo — e até Tokio — dentro de um Worker com o alvo Emscripten: os três exemplos oficiais, o que muda no modelo de thread e os limites da prévia.

- **Organização:** Escola de Aplicativos (https://www.escoladeaplicativos.com.br)
- **Autores:** Mauro Mequelussi
- **Página canônica:** https://www.escoladeaplicativos.com.br/arsenal/rust-workers-guia-exemplos
- **Publicado em:** 2026-09-29T03:10:29.978884777Z
- **Atualizado em:** 2026-09-29T03:10:29.978942338Z
- **Tags:** rust, tokio, cloudflare, open-source, workers, webassembly

---

# Rust nos Workers: exemplos para rodar no seu Worker

::callout{type="warning"}
**Ressalva de método.** Guia baseado no anúncio oficial da Cloudflare e na documentação do wasm-bindgen — **não** é um teste feito aqui. Conferido: estado (prévia experimental), os três exemplos publicados, as mudanças no Tokio e o motivo do alvo Emscripten. Não testado: compilar os exemplos nesta máquina, subir um Worker com Tokio em produção e o comportamento sob carga.
::

## O problema que isso resolve

Você tem biblioteca ou serviço em **Rust** e quer colocá-lo na borda, perto do usuário. Nos Workers, muita coisa quebrava. O Worker roda com **uma única thread**, dentro do ciclo de eventos do JavaScript, e o **Tokio** — o motor assíncrono mais usado no Rust — espera poder **travar a thread e esperar** (park) até um socket ficar legível ou um timer expirar. Os dois modelos não são compatíveis: uma espera bloqueante trava o loop de eventos compartilhado.

A saída foi um **alvo de compilação novo**: `wasm32-unknown-emscripten` no wasm-bindgen.

## Passo a passo

### 1. Entenda quem faz o quê

O **Emscripten** é o tradutor: ele virtualiza arquivos, relógio e rede sobre as mesmas interfaces de Node.js que o Workers já suporta. O programa em Rust continua achando que está num computador comum; o tradutor converte cada pedido para o que o Workers entende. O trabalho juntou o time Portable Toolchains do Google e engenheiros da Cloudflare para que o **wasm-bindgen** funcionasse com esse alvo.

### 2. Escolha o exemplo mais próximo do seu caso

Há três exemplos publicados, do mais simples ao mais completo:

::code-demo{lang="bash" title="os três exemplos oficiais (workers-rs)"}
# 1. Workers em Rust com Emscripten
git clone --depth 1 https://github.com/cloudflare/workers-rs
cd workers-rs/examples/emscripten

# 2. Tokio rodando dentro de um Worker
cd ../emscripten-tokio

# 3. Sockets TCP com Emscripten + Tokio
cd ../emscripten-tcp
::

### 3. Saiba qual problema de Tokio você vai encontrar

Para encaixar o Tokio em um host com ciclo de eventos, existem dois caminhos, e os dois estão implementados nos exemplos:

- **JSPI** (WebAssembly JavaScript Promise Integration): uma chamada bloqueante suspende a pilha do WebAssembly e devolve o controle ao loop de eventos — exatamente uma operação de park. O detalhe difícil é que o Rust **não sabe** que a própria pilha saiu de baixo dele: o contexto do runtime do Tokio vive em thread local, e troca de pilha não é troca de thread. A solução exige trocar esse contexto a cada entrada, saída, suspensão e retomada do JSPI — na prática, uma thread cooperativa multiplexada no tempo.
- **LocalEventLoop** (integração com o ciclo de eventos): o runtime do Tokio é dividido em duas partes. Em vez de **esperar** (park), ele apenas **avisa** o host que tem trabalho, e o host chama `drive()` quando quiser rodar um lote de tarefas prontas.

::code-demo{lang="rust" title="o modelo LocalEventLoop (do post da Cloudflare)"}
let el = Builder::new_current_thread()
    .enable_all()
    .build_local_event_loop(Default::default(), host_waker)?;

el.spawn_local(async {
    let mut stream = TcpStream::connect(addr).await?;
    let mut buf = [0u8; 1024];
    // o controle volta para o host enquanto espera
    let n = stream.read(&mut buf).await?;
    Ok::<_, io::Error>(())
});
::

Com esse desenho o ciclo de eventos do host **nunca fica bloqueado** e se intercala com o Tokio, um lote por vez. A mesma arquitetura embute o runtime em um `main loop` de GTK, um `message pump` do Win32 ou um run loop do Cocoa. O preço: `block_on` **não espera** nesse modo — onde um runtime normal faria park, ele entra em pânico, porque nada poderia acordar aquela future de dentro da chamada.

### 4. Sockets: o que precisou ser construído

O Tokio constrói seu driver de I/O em cima de `epoll_wait()`, que o Emscripten não suportava (só `poll()` e uma emulação por WebSocket). Foram **mais de 40 contribuições** ao Emscripten para conectar sockets TCP, UDP e Unix. É o que permite dizer "conexão TCP de verdade dentro de um Worker" e não "emulação".

### 5. O teste que mostra o teto

Um **servidor de Minecraft (Pumpkin)** rodou dentro de um **Durable Object**, com entrada TCP, usando sockets TCP reais via Tokio. Cada arquivo salvo pelo jogo virou uma linha no SQLite do objeto — e o servidor reinicia no mesmo mundo. Foi portado por um engenheiro em um fim de semana.

::callout{type="tip"}
Use isso como régua, não como promessa: se um servidor de jogo com estado persistente rodou, bibliotecas comuns de Rust tendem a portar com pouco ou nenhum ajuste. As que mexem em sistema de baixo nível (`libc`, `socket2`, `Mio`) precisaram de patch — quase sempre só para permitir o novo alvo nas condições de plataforma.
::

## Limites e cuidados

- **É prévia experimental.** Ainda antes do lançamento oficial; parte das mudanças do Tokio **aguarda aprovação upstream** nas projetos originais.
- **Os exemplos exigem os patches publicados pela Cloudflare** enquanto a integração não chega às versões oficiais — não é só atualizar uma dependência.
- **Uma thread, sem exceção.** Tudo o que você escrever tem que conviver com o modelo cooperativo; código que assume paralelismo real não passa.
- **Feedback é por canal aberto**: issues no GitHub e o canal `#rust-on-workers` no Discord da Cloudflare. Sem SLA de produto.

## Por onde começar

Comece pela biblioteca que você **já tem** e que hoje vive presa a um servidor. Clone os exemplos, rode o `emscripten` puro primeiro (é o que menos exige), e só depois tente o `emscripten-tokio` — que é onde a assimetria de modelo aparece. Se a sua biblioteca não usa Tokio nem socket, provavelmente o primeiro exemplo responde a sua pergunta em uma tarde.

- Blog do anúncio: https://blog.cloudflare.com/rust-workers-emscripten-target/
- Exemplos: https://github.com/cloudflare/workers-rs/tree/main/examples
- Documentação do alvo Emscripten no wasm-bindgen: https://wasm-bindgen.github.io/wasm-bindgen/reference/emscripten.html
