Timers & Intervals
A roda de timers do Tokio impulsiona sleep, interval, timeout e agendamento baseado em Instant sem bloquear threads de trabalho. Ative o recurso time para serviços de produção.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
use tokio::time::{sleep, Duration, timeout};
async fn work() -> &'static str {
sleep(Duration::from_millis(50)).await;
"ok"
}
#[tokio::main]
async fn main() {
let result = timeout(Duration::from_secs(1), work()).await;
println!("{:?}", result);
}Quando usar isso: Debouncing, polls periódicos, prazos de requisição, backoff de retentativa e ticks de heartbeat.
Exemplo de Funcionamento
use tokio::time::{interval, sleep, Duration, MissedTickBehavior};
#[tokio::main]
async fn main() {
let mut ticker = interval(Duration::from_millis(100));
ticker.set_missed_tick_behavior(MissedTickBehavior::Skip);
for _ in 0..3 {
ticker.tick().await;
println!("tick");
}
sleep(Duration::from_millis(250)).await;
ticker.tick().await; // pula ticks perdidos com comportamento Skip
println!("retomado");
}O que isso demonstra:
intervalproduz despertares periódicos.MissedTickBehavior::Skipevita tempestade de catch-up após atraso.sleepé um atraso de tiro único.
Mergulho Profundo
Como Funciona
- Roda de timers: Agendamento eficiente de muitos prazos.
- sleep: Atraso relativo a partir de agora.
- interval: Periódico; o primeiro tick completa imediatamente, a menos que
interval_atseja usado. - timeout: Wrapper que cancela o future interno na expiração.
Comportamento de Tick Perdido
| Modo | Comportamento |
|---|---|
Burst | Recupera todos os ticks perdidos |
Delay | Atrasa o próximo tick pelo tempo de estouro |
Skip | Reinicia o agendamento após o estouro |
Notas de Rust
use tokio::time::{Instant, Duration};
let start = Instant::now() + Duration::from_secs(1);
let mut ticker = tokio::time::interval_at(start, Duration::from_secs(5));- Use
Instantdetokio::time, nãostd::time::Instant, em testes async com pausa. - Camadas de timeouts: conexão, TTFB, requisição total.
- Backoff exponencial:
sleep(duration * 2u32.pow(attempt))com limite.
Armadilhas
- std::thread::sleep em async - Bloqueia o worker. Correção:
tokio::time::sleep. - Tempestade de catch-up de interval - O burst padrão dispara muitos ticks após a paralisação. Correção:
MissedTickBehavior::Skippara heartbeats. - Timeout muito apertado no cold start - Falhas falsas no aquecimento de JIT/conexão. Correção: Orçamento de aquecimento separado ou retentativa.
- Timer sem o recurso time - Falha de compilação/runtime. Correção:
features = ["time"]no tokio. - Assumindo precisão de relógio de parede - Timers são cooperativos sob carga. Correção: Não usar para garantias de tempo real rígido.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
cron / agendador externo | Jobs em todo o cluster | Atraso por requisição dentro do processo |
sleep em thread de bloqueio | CLI Síncrono | Contexto de worker Tokio |
tokio-cron-scheduler | Tarefas de manutenção periódicas | Temporização sub-milissegundo |
| Busy poll | Nunca | Nunca em serviços Tokio |
FAQs
sleep vs interval?
sleep uma vez; interval repete até ser descartado.
tipo de erro de timeout?
Elapsed de tokio::time::error::Elapsed - o future interno é descartado.
Testando timers?
#[tokio::test(start_paused = true)] então advance para tempo determinístico.
primeiro tick de interval imediato?
Sim por padrão - use interval_at para alinhar o primeiro disparo.
Precisão sob carga?
Timers disparam após o prazo quando o runtime consulta - não são garantias de sistema operacional em tempo real.
timeout do reqwest?
Timeout em nível de cliente complementa o wrapper timeout do Tokio - configure ambos criteriosamente.
crate backoff?
backoff ou sleep exponencial manual para retentativas com jitter.
padrão watchdog?
select! entre o trabalho e o branch sleep(deadline) para detecção de paralisação.
pausa em produção?
Não - pause é uma API apenas para testes no runtime de teste.
DelayQueue?
tokio_util::time::DelayQueue para muitos prazos com chave - timers para streams de itens expirando.
Relacionados
- Cancelamento e Timeouts - prazos
- Combinando Futures - timeout em select
- select! & Concorrência - branches de timer
- Tokio Basics - introdução ao sleep
- Encerramento Gracioso - timeouts de drenagem
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.