مقدمة :
تخيل أنك تطور متجراً إلكترونياً , حيث يقوم المستخدم بإضافة المنتجات للسلة وبعد الانتهاء يقوم بالضغط على إرسال الطلب ,
والمطلوب منك هو تخزين الطلب وإرسال إيميل للمستخدم باستلام الطلب و بنفس الوقت إعلام لوحة التحكم أو الإدارة بوجود طلب جديد ,
ثم العودة للمستخدم برسالة " تم إرسال الطلب " .
هذه المتطلبات بسيطة بالتأكيد , لكن المخيف في الموضوع هو الزمن المستغرق في هذه العمليات قبل العودة للمستخدم بحالة "تم إرسال الطلب ",
هذه العملية سوف تستغرق من 7 إلى 10 ثانية في أقل تقدير لأنها سوف تتعامل مع عدة وظائف وهي :
1• إنشاء record جديد في جدول الطلبات وجدول تفاصيل الطلب .
2• إرسال بريد الكتروني للمستخدم .
3• إرسال إشعار للوحة التحكم مثلاً عبر (pusher ) .
4• العودة للمستخدم برسالة عبر session تظهر في الواجهة .
و في حال استغراق العمليات ل 10 ثوانٍ سيظن المستخدم أن النظام في حالة خلل وسيخرج من الموقع وسيخسر عميلك طلباً وزبوناً مؤكداً .
الحل دائماً مع لارافيل :
توفر لارافيل نظاماً متكاملاً لمثل هذه العمليات يسمى بنظام الطابور Queues أو قوائم الانتظار حيث تنفذ لارافيل العمليات في الخلفية بدون شعور المستخدم عبر كلاسات الأعمال المؤجلة Jobs لتنفيذ العملية على أكمل وجه وبتنظيم متناهي السهولة .
إذاً كيف أبدأ وكيف تستعمل الطوابير :
علينا أولاً تغيير المتغيرات الخاصة بالطوابير في ملف .env وينعكس التغيير فيه على ملف queue.php الموجود في مجلد config :
• التغيير في ملف .env
QUEUE_CONNECTION=database
ويعني ذلك أنك الطوابير سوف تتعامل مع قاعدة البيانات كمحرك أساسي للعمل , مع العلم بوجود محركات أخرى سنتطرق لها في مقالات قادمة .
تتعامل الطوابير مع جدول Jobs حيث تنفذ العمليات الموجودة داخله سطراً سطراً وتعود بالنتيجة على نفس الجدول , لذلك علينا أولاً إنشاء جدول jobs عبر أمر artisan التالي في سطر الأوامر :
php artisan queue:table
php artisan migrate
السطر الاول سيقوم بإنشاء ملف Migration لجدول jobs على الشكل التالي :
public function up(){ Schema::create('jobs', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('queue')->index(); $table->longText('payload'); $table->unsignedTinyInteger('attempts'); $table->unsignedInteger('reserved_at')->nullable(); $table->unsignedInteger('available_at'); $table->unsignedInteger('created_at'); }); }
أما الأمر الثاني فيقوم بترحيل الملف السابق لقاعدة البيانات بحيث يصبح لدينا الجدول جاهزاً لاستقبال العمليات التي يقوم النظام بوضعها في الطابور .
إنشاء ملف job ( عملية ) :
يتم ببساطة عبر أمر artisan على الشكل التالي :
php artisan make:job SendOrderRecivedEmail
والنتيجة هو ملف job على الشكل التالي :
class SendOrderRecivedEmail implements ShouldQueue{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
}
public function handle()
{
}
}
يستخدم الكلاس السابق واجهة ShouldQueue والتي تعني أن استدعاء هذه العملية يعني وضعها في جدول jobs السابق , نقوم بالتعديل على الملف السابق لتمرير البيانات الخاصة بالإيميل له ليقوم بالعملية عند استدعائه على الشكل التالي :
class SendEmailJob implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $email;
public function __construct($email)
{
$this->email=$email;
}
public function handle()
{
Mail::to("[email protected]")->send(new SendEail($this->email));
}
}
لاحقاً يمكنك استدعاء هذه العملية ووضعها في الطابور , من خلال ملف controller الخاص بتنفيذ الطلب :
SendOrderRecivedEmail::dispatch($email);
كما يمكنك جدولة أو تأخير العمل لوقت قادم عبر استدعاءه على الشكل التالي :
SendOrderRecivedEmail::dispatch($email)->delay(now()->ddMinutes(10));
المراجع :