Planejador de tarefas em Rust: criando um job scheduler confiável

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Planejador de tarefas em Rust: de um simples temporizador a um job scheduler industrial



Um planejador de tarefas (job scheduler) é um dos componentes-chave de qualquer aplicação séria. Com Rust, você pode construir um sistema que executa com precisão de milissegundos, consome o mínimo de memória e funciona sem falhas por anos. Neste artigo, vamos explorar como criar um planejador de tarefas em Rust, usando tanto recursos padrão quanto crates populares.



Por que escrever um planejador em Rust?



Rust oferece uma combinação única de desempenho e segurança. Um planejador de tarefas em Rust:



  • Garante a ausência de condições de corrida (data races) — o compilador verifica isso em tempo de compilação.
  • Funciona sem coletor de lixo — latência previsível na execução de tarefas.
  • Suporta execução assíncrona e multithread.
  • Tem consumo mínimo de memória — é possível executar milhares de tarefas.


Planejador simples com std::thread::sleep



Vamos começar com um exemplo básico — execução cíclica de uma tarefa a cada N segundos:



use std::thread;use std::time::Duration;

fn main() { let interval = Duration::from_secs(5); loop { println!("[{}] Executando tarefa...", chrono::Local::now().format("%H:%M:%S")); // Aqui vai o código da sua tarefa thread::sleep(interval); }}


Essa abordagem é simples, mas ineficiente: bloqueia a thread atual e não permite executar várias tarefas em paralelo.



Planejador assíncrono com tokio



Para projetos reais, use tokio — um runtime assíncrono que permite executar milhares de tarefas em uma única thread.



use tokio::time::{interval, Duration};

#[tokio::main]async fn main() { let mut timer = interval(Duration::from_secs(10)); println!("Planejador iniciado. A tarefa será executada a cada 10 segundos."); loop { timer.tick().await; println!("[{}] Executando tarefa...", chrono::Local::now().format("%H:%M:%S")); // Tarefa assíncrona: por exemplo, uma requisição a uma API do_work().await; }}

async fn do_work() { // Simulação de trabalho útil tokio::time::sleep(Duration::from_millis(500)).await; println!("Tarefa concluída.");}


Vantagens: não bloqueia a thread, é possível executar centenas desses planejadores em paralelo.



Agendamento estilo CRON com a crate cron



Se você precisa de agendamentos complexos (como no cron do Linux), use a crate cron:



use cron::Schedule;use chrono::Utc;use std::str::FromStr;

fn main() { // A cada minuto, aos 30 segundos let expression = "30 * * * * *"; let schedule = Schedule::from_str(expression).unwrap(); println!("Próximas 5 execuções:"); for datetime in schedule.upcoming(Utc).take(5) { println!(" {}", datetime); }}


Aqui está um exemplo mais completo com execução real:



use cron::Schedule;use chrono::{Utc, Local};use std::thread;use std::time::Duration;use std::str::FromStr;

fn main() { // A cada 15 segundos let expression = "0/15 * * * * *"; let schedule = Schedule::from_str(expression).unwrap(); loop { let now = Utc::now(); if let Some(next) = schedule.upcoming(Utc).next() { let delay = next - now; let millis = delay.num_milliseconds().max(0) as u64; thread::sleep(Duration::from_millis(millis)); println!("[{}] Tarefa agendada!", Local::now().format("%H:%M:%S")); // Execução da tarefa } else { thread::sleep(Duration::from_secs(1)); } }}


Planejador industrial com multithreading



Para projetos sérios, crie uma estrutura Scheduler

Recommendations