В этом руководстве мы будем использовать 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