Planejador de Tarefas Rust: guia completo para desenvolvedores
Planejadores de tarefas são uma parte essencial do desenvolvimento moderno. Eles permitem automatizar a execução de operações rotineiras: limpeza periódica de cache, envio de notificações, sincronização de dados e muito mais. No ecossistema Rust, existem várias bibliotecas poderosas para implementar planejadores. Neste artigo, vamos analisar três abordagens principais: cron, tokio-cron-scheduler e job_scheduler.
1. Planejador básico com a biblioteca cron
A biblioteca cron fornece funcionalidade minimalista para analisar expressões cron e calcular o horário da próxima execução. Ela não contém um loop de execução embutido, por isso é frequentemente combinada com tokio ou std::thread.
Instalação:
[dependencies]cron = "0.12"chrono = "0.4"tokio = { version = "1", features = ["full"] }Exemplo de um planejador simples:
use cron::Schedule;use chrono::Utc;use std::str::FromStr;use std::thread;use std::time::Duration;
fn main() { // A cada minuto let expression = "0 * * * * *"; let schedule = Schedule::from_str(expression).unwrap();
loop { let now = Utc::now(); if let Some(next) = schedule.upcoming(Utc).next() { let duration = next - now; if duration.num_seconds() > 0 { thread::sleep(Duration::from_secs(duration.num_seconds() as u64)); } println!("[{}] Tarefa executada!", Utc::now()); } }}Esta abordagem oferece controle total, mas requer gerenciamento manual do loop. Adequada para cenários simples.
2. Planejador assíncrono tokio-cron-scheduler
Para aplicações assíncronas modernas baseadas em tokio, a biblioteca tokio-cron-scheduler é ideal. Ela fornece um planejador pronto com suporte para agendamentos cron complexos, jobs com identificadores e manipuladores de erros.
Instalação:
[dependencies]tokio-cron-scheduler = "0.10"tokio = { version = "1", features = ["full"] }Exemplo com duas tarefas:
use tokio_cron_scheduler::{Job, JobScheduler};use std::sync::Arc;
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let sched = JobScheduler::new().await?;
// Tarefa 1: a cada 5 segundos let job1 = Job::new_async("*/5 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job1] Executado em {:?}", std::time::SystemTime::now()); }) })?;
// Tarefa 2: a cada minuto let job2 = Job::new_async("0 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job2] Tarefa de minuto"); }) })?;
sched.add(job1).await?; sched.add(job2).await?; sched.start().await?;
// Mantém a aplicação em execução tokio::signal::ctrl_c().await?; println!("Planejador parado"); Ok(())}Vantagens: gerenciamento automático de tempo, suporte para remoção/pausa de tarefas, execução assíncrona sem bloqueios.
3. Planejador simples job_scheduler
A biblioteca job_scheduler é focada na máxima simplicidade. Ela não requer um runtime assíncrono e é adequada para utilitários de console ou integração em projetos síncronos existentes.
Instalação:
[dependencies]job_scheduler = "1.2"chrono = "0.4"Exemplo:
use job_scheduler::{Job, JobScheduler};use std::time::Duration;
fn main() { let mut sched = JobScheduler::new();
sched.add(Job::new("1/10 * * * * *".parse().unwrap(), || { println!("Execução da tarefa a cada Também na biblioteca
Processamento de Imagens em C# (.NET): Bibliotecas e Exemplos de Código
Gerador de QR Codes em Swift: Core Image, CIFilter e Soluções Próprias
Configuração de aplicações Node.js: melhores bibliotecas e práticas
Valibot para TypeScript: guia completo com exemplos