Planificateur de tâches en Rust : guide complet des bibliothèques et de l'implémentation
Dans le développement moderne d'applications serveur et de systèmes d'automatisation, le planificateur de tâches (task scheduler) est l'un des composants clés. Rust, grâce à ses performances et à sa sécurité mémoire, propose plusieurs solutions puissantes pour créer des planificateurs flexibles et efficaces. Dans cet article, nous examinerons en détail les principales bibliothèques pour la planification de tâches en Rust, leurs fonctionnalités, des exemples d'utilisation et une comparaison avec les équivalents en Python.
Principales bibliothèques pour la planification de tâches en Rust
L'écosystème Rust propose plusieurs solutions matures pour travailler avec les planificateurs de tâches. Examinons les trois bibliothèques les plus populaires :
- tokio-schedule — un planificateur asynchrone basé sur tokio, prenant en charge les expressions cron et les tâches à intervalles
- cron — une bibliothèque légère pour travailler avec les expressions cron, souvent utilisée avec tokio
- async-task-scheduler — un planificateur de haut niveau avec prise en charge des priorités, des répétitions et des règles d'exécution complexes
Installation et configuration de tokio-schedule
Pour commencer, ajoutez les dépendances à votre fichier Cargo.toml :
[dependencies]tokio = { version = "1.0", features = ["full"] }tokio-schedule = "0.4"chrono = "0.4"Exemple 1 : Planificateur simple avec intervalle
Créons un planificateur de base qui exécute une tâche toutes les 5 secondes :
use tokio::time::{sleep, Duration};use tokio_schedule::Job;
#[tokio::main]async fn main() { // Création d'une tâche qui s'exécute toutes les 5 secondes let job = Job::new() .every(Duration::from_secs(5)) .run(|| async { println!("Tâche exécutée à : {}", chrono::Local::now()); });
println!("Planificateur démarré. Appuyez sur Ctrl+C pour arrêter."); job.start().await; // Attente infinie loop { sleep(Duration::from_secs(1)).await; }}Exemple 2 : Planificateur avec expression cron
Un exemple plus complexe utilisant la syntaxe cron pour un contrôle précis du temps d'exécution :
use tokio_schedule::Job;use std::sync::Arc;use std::sync::atomic::{AtomicU64, Ordering};
#[tokio::main]async fn main() { let counter = Arc::new(AtomicU64::new(0)); let counter_clone = counter.clone();
// Exécution chaque minute à 30 secondes let job = Job::new() .cron("30 * * * * *") // seconde, minute, heure, jour, mois, jour_semaine .run(move || { let cnt = counter_clone.fetch_add(1, Ordering::SeqCst); async move { println!("[{}] Exécution de la tâche à : {}", cnt, chrono::Local::now()); // Votre logique métier ici simulate_work().await; } });
println!("Planificateur avec cron démarré."); job.start().await;
// Démonstration du fonctionnement pendant 2 minutes tokio::time::sleep(Duration::from_secs(120)).await;}
async fn simulate_work() { // Simulation de travail tokio::time::sleep(Duration::from_millis(500)).await;}Exemple 3 : Planificateur avec plusieurs tâches et priorités
Utilisation de la bibliothèque async-task-scheduler pour gérer plusieurs tâches :
use async_task_scheduler::{Scheduler, Task, Priority};use std::time::Duration;
#[tokio::main]async fn main() { let mut scheduler = Scheduler::new();
// Tâche haute priorité — s'exécute toutes les 2 secondes scheduler.add_task( Task::new("high_priority_task", || async { println!("[HIGH] Tâche urgente exécutée"); }) .interval(Duration::from_secs(2)) .priority(Priority::High) );
// Tâche basse priorité — ex