مجدول مهام Rust: دليل شامل للمطورين
مجدولو المهام جزء لا يتجزأ من التطوير الحديث. فهي تتيح أتمتة تنفيذ العمليات الروتينية: التنظيف الدوري للذاكرة المؤقتة، إرسال الإشعارات، مزامنة البيانات، وغيرها الكثير. في نظام Rust البيئي، توجد عدة مكتبات قوية لتنفيذ المجدولين. في هذه المقالة، سنستعرض ثلاثة مناهج رئيسية: cron و tokio-cron-scheduler و job_scheduler.
1. المجدول الأساسي مع مكتبة cron
توفر مكتبة cron وظائف بسيطة لتحليل تعبيرات cron وحساب وقت التشغيل التالي. لا تحتوي على حلقة تنفيذ مدمجة، لذلك غالبًا ما يتم دمجها مع tokio أو std::thread.
التثبيت:
[dependencies]cron = "0.12"chrono = "0.4"tokio = { version = "1", features = ["full"] }مثال لمجدول بسيط:
use cron::Schedule;use chrono::Utc;use std::str::FromStr;use std::thread;use std::time::Duration;
fn main() { // كل دقيقة 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!("[{}] تم تنفيذ المهمة!", Utc::now()); } }}يمنحك هذا النهج تحكمًا كاملاً، لكنه يتطلب إدارة يدوية للحلقة. مناسب للسيناريوهات البسيطة.
2. المجدول غير المتزامن tokio-cron-scheduler
للتطبيقات غير المتزامنة الحديثة المبنية على tokio، تعتبر مكتبة tokio-cron-scheduler مثالية. توفر مجدولًا جاهزًا مع دعم جداول cron المعقدة، والمهام ذات المعرفات، ومعالجات الأخطاء.
التثبيت:
[dependencies]tokio-cron-scheduler = "0.10"tokio = { version = "1", features = ["full"] }مثال مع مهمتين:
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?;
// المهمة 1: كل 5 ثوانٍ let job1 = Job::new_async("*/5 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job1] تم التنفيذ في {:?}", std::time::SystemTime::now()); }) })?;
// المهمة 2: كل دقيقة let job2 = Job::new_async("0 * * * * *", |_uuid, _lock| { Box::pin(async move { println!("[Job2] مهمة الدقيقة"); }) })?;
sched.add(job1).await?; sched.add(job2).await?; sched.start().await?;
// إبقاء التطبيق قيد التشغيل tokio::signal::ctrl_c().await?; println!("تم إيقاف المجدول"); Ok(())}المزايا: إدارة تلقائية للوقت، دعم حذف/إيقاف المهام مؤقتًا، تنفيذ غير متزامن بدون حظر.
3. المجدول البسيط job_scheduler
مكتبة job_scheduler موجهة نحو أقصى درجات البساطة. لا تتطلب بيئة تشغيل غير متزامنة ومناسبة للأدوات الطرفية أو التضمين في المشاريع المتزامنة الحالية.
التثبيت:
[dependencies]job_scheduler = "1.2"chrono = "0.4"مثال:
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!("تنفيذ المهمة كل