Как планировать и запускать задания cron в Rust с помощью apalis

В этом руководстве мы будем использовать apalis для запуска заданий cron в асинхронном контексте. Мы также рассмотрим, как украсить наши задания промежуточным программным обеспечением tower, позволяющим нам разблокировать такие функции, как retries, prometheus, sentry и т.д.

Для начала нам потребуется:

Создать новый проект

cargo new my-cron-scheduler
cd my-cron-scheduler
Войти в полноэкранный режим Выйти из полноэкранного режима

Добавить в Cargo.toml

[dependencies]
apalis = { version = "0.3", features = ["cron"] }
serde = { version = "1.0", features = ["derive"] }
tower = 0.4
Войти в полноэкранный режим Выйти из полноэкранного режима

В этом руководстве мы создадим пример ежедневного напоминания.

use apalis::prelude::*;
use serde::{Serialize,Deserialize};

#[derive(Serialize, Deserialize, Default, Debug, Clone)]
struct Reminder;

// Define an apalis job
impl Job for Reminder {
    const NAME: &'static str = "reminder::DailyReminder";
}
// Define a handler
async fn send_reminder(job: Reminder, ctx: JobContext) {
    // Do reminder stuff
}
Войти в полноэкранный режим Выход из полноэкранного режима

Определим точку входа

use apalis::cron::{CronWorker, Schedule};
#[tokio::main]
async fn main() {
    // any valid cron string that points to the future should work
    let schedule = Schedule::from_str("@daily").unwrap();

    let worker = CronWorker::new(schedule, job_fn(send_reminder));

    Monitor::new()
        .register(worker)
        .run()
        .await
        .unwrap();
}
Вход в полноэкранный режим Выход из полноэкранного режима

Это работает отлично, но мы можем добавить некоторые дополнительные функции, например, повторные попытки и расширения контекста задания.

Чтобы использовать эти функции в apalis, вам нужно включить функции retry и extension.

use apalis::layers::{Extension, DefaultRetryPolicy, RetryLayer};

#[derive(Clone)]
struct FakeService;

let service = ServiceBuilder::new()
    // Will retry 25 times
    .layer(RetryLayer::new(DefaultRetryPolicy))
    .layer(Extension(FakeService))
    .service(job_fn(send_reminder));

let worker = CronWorker::new(schedule, service);

Monitor::new()
    .register(worker)
    .run()
    .await
    .unwrap();

Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы можем получить доступ к нашему FakeService в нашем обработчике

// Define a handler
async fn send_reminder(job: Reminder, ctx: JobContext) {
    let fake_service = ctx.data_opt::<FakeService>();
    // fake_service.fetch_from_db()
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете повторить этот процесс для разных заданий cron.

Monitor::new()
    .register(daily_worker)
    .register(weekly_worker)
    .run()
    .await
    .unwrap();
Вход в полноэкранный режим Выход из полноэкранного режима

Дополнительное чтение:
Фоновая обработка заданий с помощью rust с использованием apalis, actix и redis
Apalis на Github

Оцените статью
devanswers.ru
Добавить комментарий