Crate periodically

Source
Expand description

Periodically provides a robust and ergonomic library for writing periodic or scheduled jobs in Rust.

§The Scheduler

The Scheduler is the core of periodically. It allows for tasks to be registered and scheduled. It supports running synchronous Tasks and asynchronous AsyncTasks in the same scheduling runtime.

The core design of the scheduler is based on the idea of decoupling an executable task from it’s schedule.

For example, consider how this naive example of a periodic job requires so much boilerplate:

std::thread::spawn(move || {
  loop {
    // ..
    // do the actual work
    // ..
    if should_terminate {
        break;
    }
    std::thread::sleep(Duration::from_millis(100));
  }
});

This example also fails to account for edge cases like panic resilience.

Whereas with periodically, the task can easily without worrying about the schedule, and then the schedule can be injected later. This also enables the re-use of schedules if there is common specialized logic for your application.

impl Task for MyTask {
  fn run(&self) {
    // ..
    // do the actual work
    // ..
  }
}
let mut scheduler = Scheduler::tokio_scheduler(runtime);
scheduler.add_sync_task(MyTask {}, IntervalSchedule::every(Duration::from_secs(100)));

Scheduler executes tasks in a serial fashion. aka; for every time a task is registered, there is only ever at most one execution of that task.

§Tasks

There are 2 types of task. The synchronous Task, and it’s async counterpart AsyncTask. Their interfaces are very similar, with the major difference being that AsyncTask returns a future that is Send.

Both types of task can be scheduled on the same Scheduler, via add_sync_task and add_async_task respectively.

§Schedules

The primary function of a Schedule is to consume context from a task execution, and decide when the next time that task will be executed.

There are 3 control knobs of a Schedule:

  1. initial - this is called the very first time a task is being scheduled for execution.
  2. next - this is called with the output of the last task execution.
  3. next_on_task_panic - this is called when the last task execution panicked.

By using these knobs, and the internal state of the impl Schedule, there is a lot of flexibility in how dynamic schedulers can be built. Additionally, since next takes the output of the last task execution, an impl Schedule provides a way to egress execution data via mechanims like mpsc channels if desired.

§Features

By default, the only features enabled are tokio and log

  • full: Enables all features
  • tokio: Enables the tokio-based scheduler. As of 0.2.0, this is the only scheduler, and essentially required.
  • log: Enables an intergration with the log crate in the Scheduler. Helps provide debug information when dealing with problematic tasks.
  • backoff: Adds a built-in Schedule named BackoffSchedule which uses the external backoff crate.
  • cron: Adds a built-in Schedule named CronSchedule which uses the external cron crate.

Structs§

BackoffSchedulebackoff
Backs off using a BackoffSchedule from the backoff crate.
CronSchedulecron
Runs jobs periodically based on a CronSchedule from the cron crate.
IntervalSchedule
Schedules a simple interval execution.
OneShot
Schedules a single (‘one shot’) execution after a specified delay of time.
Scheduler
The core scheduler of periodically. Provides the interfaces for scheduling individual tasks.
TaskIdentifier
Task Identifiers are created by a Scheduler when registering a task, and are used for performing modifications on a running task with a scheduler.

Traits§

AsyncTask
Defines a task that can run in an asynchronous runtime.
Schedule
Defines an execution schedule for a given task. All duration values returned define how long until the task should start execution.
Task
Defines a task that can run in an synchronous runtime.