Scheduler (Cron)
Relevant source files
The following files were used as context for generating this wiki page:
The Scheduler module in Loco provides a high-level, elegant alternative to traditional crontab systems for scheduling recurring tasks or shell scripts within a Rust application. It simplifies the orchestration of background operations by allowing developers to define jobs in YAML configurations, supporting both standard cron syntax and human-readable English expressions.
Integrated deeply with the Loco ecosystem, the scheduler can execute internal application Tasks or external shell commands. It manages execution environments, handles job output (silent or stdout), and allows for job filtering via names or tags.
Sources: src/scheduler.rs:1-15, docs-site/config.toml:175-178
Core Architecture and Data Structures
The scheduler is built around a central Scheduler struct that manages a collection of Job definitions. It leverages tokio-cron-scheduler for the underlying execution timing.
Data Model
The following diagram illustrates the relationship between the configuration and execution components of the scheduler:
The Scheduler uses a Config structure to deserialize settings from YAML, where each Job represents a specific unit of work. Sources: src/scheduler.rs:56-100
Key Components
| Component | Description |
|---|---|
Scheduler | The main engine responsible for loading configurations, filtering jobs, and starting the cron loop. |
Job | Defines what to run (run), how to run it (shell), and when (cron). |
JobDescription | A processed version of a Job ready for execution, containing the full command string. |
Output | An enum determining if job output is sent to STDOUT or suppressed (Silent). |
Sources: src/scheduler.rs:56-150
Configuration and Command Execution
Jobs are typically defined in a scheduler.yaml file. The scheduler supports two execution modes:
- Task Mode: Executes internal Loco tasks using the current binary.
- Shell Mode: Executes raw shell commands.
Command Preparation
When a job is prepared for execution, the prepare_command function determines the final string to be executed. If shell is false, it prefixes the command with the current executable path and the task keyword.
pub fn prepare_command(
&self,
binary_path: &Path,
default_output: &Output,
environment: &Environment,
) -> JobDescription {
let command = if self.shell {
self.run.clone()
} else {
[
binary_path.display().to_string(),
"task".to_string(),
self.run.clone(),
]
.join(" ")
};
JobDescription {
command,
output: self.output.clone().unwrap_or_else(|| default_output.clone()),
environment: environment.clone(),
}
}
Sources: src/scheduler.rs:163-186
CLI Usage and Management
The Loco CLI provides several subcommands for interacting with the scheduler. These commands allow for listing, filtering, and manually triggering jobs.
Scheduler CLI Parameters
| Flag/Arg | Long Flag | Description |
|---|---|---|
-n | --name | Run a specific job by its name. |
-t | --tag | Run jobs associated with a specific tag. |
-c | --config | Specify a custom path to a scheduler configuration file. |
-l | --list | List all configured jobs and their schedules. |
Sources: src/cli.rs:114-128, snipdoc.yml:105-120
Examples of CLI Interaction
Users can list jobs or run specific maintenance tasks using the following commands:
cargo loco scheduler --list: Shows all jobs in a table format.cargo loco scheduler --tag maintenance: Filters and runs only jobs tagged with "maintenance".cargo loco generate scheduler: Generates a template scheduler configuration file.
Sources: snipdoc.yml:102-120, src/cli.rs:438-442
Job Execution Lifecycle
The scheduler uses tokio for asynchronous execution. The lifecycle involves setting up one-shot jobs for run_on_start entries and recurring jobs for the cron schedules.
The execution uses duct_sh::sh_dangerous to run the commands in the appropriate environment (e.g., development, production) by setting the LOCO_ENV environment variable.
Sources: src/scheduler.rs:191-205, src/scheduler.rs:271-331
Summary
The Scheduler module acts as a robust orchestration layer within Loco, bridging the gap between static configurations and dynamic task execution. By supporting both internal tasks and external shell scripts, it provides developers with a unified interface for all background automation needs. Its integration with the Loco CLI and support for environment-specific configurations ensures it is production-ready and developer-friendly.