Rust Task Scheduler: Library Overview and Code Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Rust Task Scheduler: A Complete Guide for Developers



Task schedulers are an essential part of modern development. They allow you to automate routine operations: periodic cache cleanup, sending notifications, data synchronization, and much more. In the Rust ecosystem, there are several powerful libraries for implementing schedulers. In this article, we will cover three main approaches: cron, tokio-cron-scheduler, and job_scheduler.



1. Basic Scheduler with the cron Library



The cron library provides minimalistic functionality for parsing cron expressions and calculating the next run time. It does not contain a built-in execution loop, so it is often combined with tokio or std::thread.



Installation:

[dependencies]cron = "0.12"chrono = "0.4"tokio = { version = "1", features = ["full"] }


Example of a simple scheduler:

use cron::Schedule;use chrono::Utc;use std::str::FromStr;use std::thread;use std::time::Duration;

fn main() { // Every minute 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!("[{}] Task executed!", Utc::now()); } }}


This approach gives you full control but requires manual loop management. It is suitable for simple scenarios.



2. Async Scheduler tokio-cron-scheduler



For modern async applications based on tokio, the tokio-cron-scheduler library is ideal. It provides a ready-made scheduler with support for complex cron schedules, jobs with identifiers, and error handlers.



Installation:

[dependencies]tokio-cron-scheduler = "0.10"tokio = { version = "1", features = ["full"] }


Example with two tasks:

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?;

// Task 1: every 5 seconds let job1 = Job::new_async("*/5 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job1] Executed at {:?}", std::time::SystemTime::now()); }) })?;

// Task 2: every minute let job2 = Job::new_async("0 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job2] Minute task"); }) })?;

sched.add(job1).await?; sched.add(job2).await?; sched.start().await?;

// Keep the application running tokio::signal::ctrl_c().await?; println!("Scheduler stopped"); Ok(())}


Advantages: automatic time management, support for deleting/pausing tasks, non-blocking async execution.



3. Simple Scheduler job_scheduler



The job_scheduler library is focused on maximum simplicity. It does not require an async runtime and is suitable for console utilities or embedding into existing synchronous projects.



Installation:

[dependencies]job_scheduler = "1.2"chrono = "0.4"


Example:

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!("Executing task every

Recommendations