المكتبة Active Job في ريلز

من موسوعة حسوب

إن Active Job هو إطار عمل مخصص للتصريح عن الوظائف وتنفيذها على مختلف أنواع الطوابير الخلفية (queuing backend). يمكن أن تكون هذه الوظائف أي شيء بدءًا من عمليات التنظيف المجدولة بشكل منتظم وحتى قيم الفواتير وإرسال رسائل البريد. بعبارة أخرى، يمكن أن تكون هذه الوظائف أي شيء يمكن تجزئته إلى وحدات صغيرة وتنفيذها سويةً على التوازي.

يمكن استعمال هذا الإطار أيضًا كواجهة خلفية لوظيفة تسليم البريد الإلكتروني عبر التابع deliver_later الذي يخص Action Mailer مما يسهِّل عدُّ أي عملية إرسال على أنها وظيفة يراد تنفيذها جدولتها لتنفيذها لاحقًا. هذا أشهر الأمثلة الشائعة عن استعمال Active Job في تطبيقات الويب الحديثة: إرسال رسائل البريد الإلكتروني خارج دائرة الطلب والإجابة (request-response cycle)، لذا لا حاجة للمستخدم أن ينتظرها.

الغرض الأساسي هو التأكد من أن جميع تطبيقات ريلز تملك بنية تحتية لوظيفة واحدة على الأقل حتى لو كان التطبيق مبني على نمط «التنفيذ المباشر» (immediate runner). يمكننا بعد ذلك الحصول على ميزات إطار العمل والجواهر الأخرى المبينة عليه دون القلق حيال اختلاف الواجهة البرمجية بين Delayed Job و Resque. تصبح عملية اختيار واجهة الطابور الخلفية أكثر من مجرد اهتمام متعلق بالتشغيل. وستكون قادرًا على التبديل واجهات الطابور الخلفية دون الحاجة إلى إعادة كتابة الوظائف الخاصة بك.

يمكنك قراءة المزيد حول Active Job في دليل أساسيات Active Job.

الاستعمال

إن أردت تعلم كيفية استعمال واجهة الطابور الخلفية المفضلة لديك، فاطلع على توثيق المحول الخاص بها في ActiveJob::QueueAdapters.

إليك مثال عن التصريح عن وظيفة ما:

class MyJob < ActiveJob::Base
  queue_as :my_jobs

  def perform(record)
    record.do_work
  end
end

وإدراج هذه الوظيفة ضمن الطابور:

MyJob.perform_later record  
# وضع الوظيفة في الطابور لتنفيذها في أقرب فرصة ينفذ فيها الطابور ويحين دورها
MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)  
# وضع الوظيفة في الطابور لتنفيذها غدًا صباحًا عند الظهيرة
MyJob.set(wait: 1.week).perform_later(record) 
# وضع الوظيفة في الطابور لتنفيذها بعد أسبوع من الآن

هذا كل ما في الأمر.

دعم GlobalID

إن Active Job يدعم سلسلة GlobalID من أجل المعاملات. هذا يجعل بالإمكان تمرير كائنات Active Record حية إلى وظيفتك بدلًا من الزوج صنف/مُعرِّف (class/id) والذي يتوجب عليك حينها إلغاء السلسلة يدويًّا. سابقًا، ستبدو الوظائف بالشكل التالي:

class TrashableCleanupJob
  def perform(trashable_class, trashable_id, depth)
    trashable = trashable_class.constantize.find(trashable_id)
    trashable.cleanup(depth)
  end
end

والأن يمكنك ببساطة كتابة ما يلي:

class TrashableCleanupJob
  def perform(trashable, depth)
    trashable.cleanup(depth)
  end
end

هذا يعمل مع أي صنف يمكن خلطه مع GlobalID::Identification والذي خُلِطَ افتراضيًّا مع أصناف Active Record.

أنظمة الطوابير المدعومة

يملك Active Job محولات مضمَّنة من أجل واجهات خلفية متعددة لوضع الأشياء ضمن طابور (queuing backends) منها Sidekiq، و Resque، و Delayed Job، وغيرها. للحصول على قائمة شاملة بالمحولات، اطلع على توثيق واجهة ActiveJob::QueueAdapters البرمجية.

ملاحظة مهمة: لم نعد نقبل طلبات الرفع على المستودع (pull requests) لإضافة محولات جديدة. نشجع صاحبي المكتبات على توفير محول ActiveJob كجزء من جوهرتهم، أو كجوهرة منفردة. لمناقشة ذلك، اطلع على المناقشات التالية: 23311، و 21406، و 32285.

الجواهر المساعدة

التنزيل والتثبيت

يمكنك تثبيت أحدث إصدار من Active Job مع RubyGems:

$ gem install activejob

كما يمكنك أيضًا تنزيل الشيفرة المصدرية كجزء من مشروع ريلز على GitHub.

مصادر