Laravel / المتقدم / الدرس 13
الطوابير والمهام الآمنة عند التكرار
صمّم العمل المؤجل حول إعادة المحاولة وهوية العمل الدائمة وحدود المعاملة بدل افتراض تنفيذ واحد مضمون.
في هذه الصفحة
أهداف الدرس
- شرح التسليم القابل للتكرار والنتيجة التجارية الثابتة عنده.
- تنسيق تثبيت قاعدة البيانات وإرسال المهام.
- اختيار إعادة محاولة ومهل محدودة ورصد الفشل.
قد تُحاول المهمة أكثر من مرة
يفصل الطابور قبول الطلب من عمله، وقد يفشل العامل بعد الأثر وقبل إقرار الإكمال. صمّم العملية الدائمة لتحتمل التكرار وفق المشغل. تستخدم التجربة الحدث evt-17 للفاتورة 17 وتعديلًا بعشر وحدات؛ فلا ينبغي تكراره. تعني الخاصية حفظ النتيجة المقصودة لهوية العملية نفسها، لا تنفيذ كل عبارة مرة أو سلامة الإعادة دون تصميم.
فصل هوية العملية عن المحاولة
اختر معرّفًا يبقى عبر المحاولات كهوية حدث ثابتة لا عشوائيًا جديدًا داخل كل محاولة. يوضح نموذج PHP إزالة التكرار في عملية واحدة ويختبر الحساب فقط. المصفوفة ليست دائمة أو مشتركة أو تنفيذًا موزعًا. يلزم قيد فريد ومعاملة تجمع الإيصال والتغيير المحلي. تحتاج المدفوعات والبريد بروتوكول المزود؛ فلا يثبت علم محلي أثرًا بعيدًا ذريًا.
<?php
declare(strict_types=1);
$events = [
["id" => "evt-17", "units" => 10],
["id" => "evt-17", "units" => 10],
["id" => "evt-18", "units" => 5],
];
$seen = [];
$total = 0;
foreach ($events as $event) {
if (isset($seen[$event["id"]])) { continue; }
$total += $event["units"];
$seen[$event["id"]] = true;
}
echo $total, " ", count($seen), PHP_EOL;
15 2
يسهم evt-17 مرة ويضيف evt-18 خمسًا، فيكون المجموع خمس عشرة لهويتين. لا يبدأ تطبيق Laravel أو طابور.
إرسال العمل بعد تثبيت الحالة اللازمة
قد يقرأ العامل الفاتورة قبل تثبيت معاملتها. تؤخر afterCommit الإرسال حتى التثبيت وتلغي ذلك الإرسال عند التراجع. يفترض المقطع Invoice بحقل status ومهمة GenerateInvoice تقبل المعرّف وتعالج التكرار بنفسها؛ ولا تُشغّل هذه الاعتماديات هنا. يفيد التأخير للترتيب، وقد يتطلب انهيار العملية بين التثبيت والنشر outbox أو تنسيقًا دائمًا إذا لزم تسليم مضمون.
<?php
use App\Jobs\GenerateInvoice;
use Illuminate\Support\Facades\DB;
DB::transaction(function () use ($invoice): void {
$invoice->update(["status" => "ready"]);
GenerateInvoice::dispatch($invoice->getKey())->afterCommit();
});
الملاحظة المتوقعة بتجربة تطبيق معزولة: يُنشر العمل بعد التثبيت الخارجي ويُلغى هذا الإرسال عند التراجع. لا يدّعي المقطع اختبار قاعدة أو طابور.
تحديد المحاولات دون خلط الأقفال بثبات النتيجة
حدّد المحاولات والتراجع والمدة ومهل الإدخال من القياس والاعتمادية. اجعل مهلة العامل أقصر بما يكفي من retry_after؛ وتستخدم SQS مهلة الرؤية. تنسق المهام الفريدة وWithoutOverlapping الإرسال أو التزامن ولا تثبت أثرًا خارجيًا واحدًا. يلزم مخزن قفل مشترك. صغّر الحمولة ولا تضع الأسرار فيها وتعامل مع تغير السجل أو حذفه قبل التنفيذ.
رصد التكرار ومسارات الاستعادة
اختبر التكرار والفشل قبل التثبيت وبعد الأثر وغياب الهدف. يفحص Queue fake نية الإرسال ولا ينفذ المعالج أو يحاكي المشغل؛ ولا يثبت الاتصال المتزامن توقيت عامل مستقل. سجّل الهوية والمحاولة والنتيجة والإصدار دون حمولة حساسة. راقب الفشل والتأخر بأهداف التطبيق. احفظ الهوية والسياق عند الإعادة؛ فقد تتجاوز هوية جديدة الحماية.
الأخطاء الشائعة وإصلاحها
تعيد المحاولة تعديل الفاتورة مرتين.
- لماذا يحدث؟
- خُلط تسليم المحاولة بهوية عملية فريدة.
- كيف تصلحه؟
- استخدم هوية ثابتة وحماية دائمة للتكرار.
- كيف تتجنب تكراره؟
- اختبر الفشل بعد الأثر لا قبله فقط.
عامل لا يجد فاتورة جديدة.
- لماذا يحدث؟
- عملت المهمة قبل تثبيت المعاملة.
- كيف تصلحه؟
- استخدم الإرسال بعد التثبيت وتعامل مع الحذف الحقيقي.
- كيف تتجنب تكراره؟
- اختبر مساري التثبيت والتراجع منفصلين.
عاملان يعالجان محاولة طويلة معًا.
- لماذا يحدث؟
- سمح توقيت الإعادة بمحاولة قبل إنهاء السابقة.
- كيف تصلحه؟
- وائم المهل مع المشغل واحفظ معالجة التكرار.
- كيف تتجنب تكراره؟
- قِس المدد وراقب المحاولات بدل قيم عامة.
اختبر فهمك
1. تتلقى التجربة evt-18 مرة أخرى. حدّد النتيجة وما يتغير بعد إعادة العملية.
اعرض الحل المشروح
في النموذج نفسه يبقى المجموع خمس عشرة والعد اثنين. تضيع المصفوفة بعد الإعادة فتُقبل النسخ. يحل إيصال دائم بمفتاح فريد ومعاملة للتغيير المحلي مسألة الاستمرار ولا يضم مزودًا بعيدًا ذريًا.
2. تتراجع المعاملة بعد جدولة GenerateInvoice بـafterCommit. حدّد الإرسال واختبارًا باقيًا للمعالج.
اعرض الحل المشروح
يُلغى الإرسال المعلق فلا تنشر مهمة للحالة المتراجع عنها. نفّذ المعالج مرتين للعملية المثبتة في تجربة معزولة وافحص نتيجة واحدة. لا يثبت fake الإرسال ثبات المعالج أو سلوك المشغل.
أهم ما تعلمته
- أدخل تكرار التسليم في عقد العمل.
- يختلف ترتيب التثبيت من التسليم الدائم.
- لا تثبت الأقفال والمحاكاة والتزامن أثرًا واحدًا مضمونًا.