مخطط المهام بلغة Go (Golang): من ticker البسيط إلى cron الصناعي
مخطط المهام (task scheduler) هو مكون يسمح بتنفيذ وظائف معينة في وقت محدد أو بوتيرة دورية. في نظام Go (Golang) البيئي، توجد عدة طرق لتنفيذ المخطط: من البدائيات المدمجة في اللغة إلى مكتبات خارجية قوية. في هذه المقالة، سنشرح كيفية إنشاء مخطط مهام بلغة Go، بدءًا من الأمثلة البسيطة وصولاً إلى استخدام المكتبة الشهيرة robfig/cron.
لماذا نحتاج إلى مخطط مهام في Go؟
Go مثالية لإنشاء تطبيقات خادم عالية الأداء، والخدمات المصغرة، وأدوات سطر الأوامر. يسمح مخطط المهام بأتمتة العمليات الروتينية:
- تنظيف ذاكرة التخزين المؤقت أو الملفات المؤقتة
- إرسال الإشعارات الدورية (البريد الإلكتروني، الرسائل النصية)
- جمع المقاييس والمراقبة
- مزامنة البيانات مع واجهات برمجة التطبيقات الخارجية (API)
- إنشاء التقارير وفقًا لجدول زمني
مخطط أساسي باستخدام time.Ticker
أبسط طريقة لتنفيذ مهمة كل N ثانية هي استخدام time.Ticker. هذه الأداة المدمجة في Go ترسل قيمة إلى القناة على فترات زمنية محددة.
package main
import ( "fmt" "time")
func main() { ticker := time.NewTicker(2 * time.Second) done := make(chan bool)
go func() { for { select { case <-ticker.C: fmt.Println("تم تنفيذ المهمة:", time.Now().Format(time.RFC3339)) case <-done: ticker.Stop() return } } }()
// إيقاف المخطط بعد 10 ثوانٍ time.Sleep(10 * time.Second) done <- true fmt.Println("تم إيقاف المخطط")}يقوم هذا الكود بإنشاء goroutine تطبع الوقت الحالي كل ثانيتين. لاحظ استخدام select - هذا هو النمط الأساسي في Go للمعالجة غير المحظورة لقنوات متعددة.
مخطط بجدول زمني مرن: مكتبة robfig/cron
للمشاريع الحقيقية التي تتطلب جدولًا زمنيًا مشابهًا لـ cron (على سبيل المثال، "كل يوم اثنين الساعة 9:00" أو "كل 5 دقائق من الساعة 9 إلى 18")، فإن المكتبة github.com/robfig/cron/v3 هي الأنسب. وهي تدعم بالكامل بناء الجملة القياسي لـ cron وتضيف ميزات مفيدة مثل العمل مع المناطق الزمنية ومعالجة الأخطاء (panics).
التثبيت
go get github.com/robfig/cron/v3مثال على الاستخدام
package main
import ( "fmt" "log" "time"
"github.com/robfig/cron/v3")
func main() { c := cron.New(cron.WithSeconds()) // تفعيل دعم الثواني
// إضافة مهمة: كل 10 ثوانٍ _, err := c.AddFunc("*/10 * * * * *", func() { fmt.Println("المهمة 1: كل 10 ثوانٍ", time.Now().Format(time.RFC3339)) }) if err != nil { log.Fatal(err) }
// مهمة: كل يوم الساعة 14:30 بتوقيت UTC _, err = c.AddFunc("0 30 14 * * *", func() { fmt.Println("المهمة 2: يوميًا الساعة 14:30 UTC") }) if err != nil { log.Fatal(err) }
// مهمة باسم للإدارة اللاحقة entryID, _ := c.AddFunc("@every 1m", func() { fmt.Println("المهمة 3: كل دقيقة") })
c.Start()
// حذف المهمة بعد 5 دقائق time.Sleep(5 * time.Minute) c.Remove(entryID) fmt.Println("تم حذف المهمة 3")
// حظر main select {}}تدعم المكتبة عدة تنسيقات للجدول الزمني:
- cron القياسي:
"30 * * * *"- كل 30 دقيقة - مع الثواني:
"0 30 * * * *"- في الثانية 30 من كل دقيقة - @every:
"@every 5m"- كل 5 دقائق أيضاً في المكتبة
توصيات