قد يرسل نظام حدثاً عن إنشاء طلب، ثم لا يتلقى تأكيداً من تطبيقك بسبب انقطاع لحظي. يعيد المرسل المحاولة، بينما يكون التطبيق قد نفذ الخطوة الأولى فعلاً. هنا تظهر المشكلة: نجاح النقل لا يثبت وحده أن الأثر حدث مرة واحدة. يمكن لمشاريع تخرج هندسة البرمجيات بناء مختبر محلي يولد أحداث Webhook، ويغير ترتيب وصولها، ثم يراقب هل سجل المستهلك الحدث مرتين أو أخفى فشلاً. المختبر لا يحتاج إلى حساب دفع ولا إلى إرسال طلبات نحو خدمة عامة.

ابدأ بعقد حدث صغير

اختر نوع حدث واحداً، مثل تغيير حالة حجز تجريبي، وحدد له معرفاً ثابتاً ووقت إنشاء ونسخة مخطط وبيانات قليلة. افصل معرف الحدث عن معرف الطلب: قد يتعلق حدثان مختلفان بالطلب نفسه، بينما إعادة التسليم للحدث ذاته يجب أن تحتفظ بالمعرف. اجعل المرسل والمستهلك برنامجين محليين، واكتب ترتيب الحالات المتوقع قبل كتابة المعالج. توضح وثائق GitHub لمعالجة التسليمات الفاشلة أن إعادة التسليم تحتاج معالجة مقصودة؛ لا تفترض أن كل منصة ستعيد تلقائياً ما فشل. أما RFC 9110 فيشرح دلالات HTTP، ومنها معنى idempotent للطلبات، لكن ذلك لا يجعل أثر تطبيق Webhook آمناً تلقائياً.

اربط الأثر بمعرف قابل لإعادة الاستخدام

قبل تعديل سجل الحجز، يكتب المستهلك معرف الحدث في جدول استقبال له قيد فريد، أو يفحصه ضمن معاملة مع تحديث الحالة. عند تكرار المعرف، يرجع نتيجة معروفة ولا يكرر البريد أو إنشاء الفاتورة. عند فشل المعاملة قبل الحفظ، يسمح الاختبار بإعادة المحاولة؛ وعند نجاح الأثر وتعطل الرد، يجب أن يمنع القيد تنفيذ الأثر ثانية. هذا نمط تصميم يحتاج اختياراً حسب قاعدة البيانات والعملية، وليس وعداً بأن كل نظام يحقق exactly-once.

يمكن للمختبر تسجيل received_at وevent_id وattempt ونتيجة المعالجة وسبب الفشل. لا تخزن أسراراً حقيقية في سجل التجربة. إذا كان هناك أثر خارجي غير قابل للإرجاع، مثل إرسال بريد، استبدله في النسخة الأولى بصندوق محلي يضيف رسالة إلى قائمة. يصبح عدد الرسائل المرئية مقياساً يمكن فحصه، بينما تظل قاعدة البيانات قابلة لإعادة الإنشاء.

اصنع إعادة تسليم قابلة للتكرار

اكتب طابور اختبار يستطيع إرسال الحدث مرة، ثم إعادته بالمعرف نفسه، ثم إرسال حدثين بترتيب معكوس. أضف تأخيراً مصطنعاً وفشلاً قبل الرد وبعد حفظ الأثر، مع بذرة عشوائية ثابتة كي تتكرر الحالة عند التصحيح. لا تخلط انقطاع الاتصال مع رفض التوقيع؛ سجّل سبب كل محاولة. حقل attempt في المختبر يصف محاولته هو، ولا تنسبه إلى ترويسة معيارية ما لم توثق منصة بعينها ذلك.

مثال: الحدث evt-21 ينقل طلباً من pending إلى confirmed. أرسل نسخة ثانية من evt-21 بعد تأكيد الحالة. ينبغي أن يظهر سجل استقبال واحد ونتيجة المعالجة المكررة، لا حجز ثانٍ. ثم أرسل evt-22 لإلغاء الطلب؛ هذه هوية جديدة ولها أثر مختلف. قارن حالة قاعدة البيانات وعدد عناصر الصندوق المحلي بعد كل خطوة. سمّ بيانات الاختبار بوضوح ولا تعرضها كقياس لمنصة إنتاج.

افصل سلامة الرسالة عن تكرارها

إذا استعملت توقيع HMAC في مختبرك، احسبه على جسم الرسالة الخام وسر تجريبي محلي، ثم قارن التوقيع بطريقة ثابتة الزمن قدر الإمكان. غيّر بايتاً واحداً في الجسم واختبر الرفض، وجرّب وقتاً خارج نافذة القبول. لا تحفظ السر في المستودع ولا تسجله في trace. التوقيع يدل على أن الرسالة طابقت المفتاح المستخدم في الاختبار؛ لا يثبت أن محتواها صحيح أو أن الحدث لم يصل سابقاً. لذلك يحتاج المستهلك إلى فحص هوية الحدث والصلاحية معاً.

تجعل المنصة الوهمية واجهة تعرض حالة التوقيع والتكرار منفصلتين: صالح وجديد، صالح ومكرر، غير صالح، أو قديم. هذا يمنع عبارة عامة مثل «آمن» من إخفاء سبب الرفض. إن أضفت تدوير مفاتيح لاحقاً، وثق أي مفتاح وقع كل رسالة وكيفية سحب مفتاح قديم، ولا تختبر ذلك بمفاتيح تستخدمها خدمة فعلية.

قِس حالات النجاح والفشل

جهز اختبارات لحدث صحيح، معرف مكرر، جسم معدّل بعد التوقيع، توقيع ناقص، وصول الحدث الثاني قبل الأول، توقف المستهلك بعد حفظ الأثر، وانتهاء مهلة المرسل. خط الأساس هو مستهلك بسيط يطبق التغيير مباشرة من دون سجل idempotency. قارن عدد الطلبات التي حدثت، عدد الرسائل المحلية، والصفوف الناتجة. يجب أن يشرح كل فشل الخطوة التي وقعت فيها، لا أن يكتفي برمز خطأ.

أعد تشغيل المجموعة ببذرة واحدة ثم ببذور أخرى، واحتفظ بملف النتائج مع إصدار التطبيق وإعداد التأخير. إذا كانت النتيجة غير حتمية، اعرضها بدلاً من حذفها. اختبر أن إعادة البناء من الصفر تعيد الحالة نفسها، وأن إعادة الحدث بعد انتهاء سجل منع التكرار معلّمة كحالة تحتاج سياسة retention. لا تفترض أن حذف سجل قديم آمن لجميع الأحداث.

حدود نسخة مشروع التخرج

تتكون النسخة الأولى من مولد حدث محلي، مستهلك ذي قيد فريد، واجهة trace، وستة اختبارات قبول. سلّم مخطط البيانات، سياسة إعادة المحاولة، جدول حالات، وشرح حدود تجربة التسليم. قصر النطاق على عملية واحدة ومعالج واحد يساعد على إثبات العلاقة بين التكرار والأثر قبل إضافة التوازي. يمكن تنظيم العمل ضمن مشاريع التخرج أو الاستفادة من تطوير المشاريع البرمجية الجامعية. لا يثبت المختبر أن كل مزود Webhook يتصرف بالطريقة نفسها، ولا يقدم ضمان تسليم أو منع خسارة؛ يجب اختبار سياسة كل مزود على وثائقه وبيئته المصرح بها.

المصادر

مراجعة المصادر: .

اختبار المثال وحدوده

سيناريو إعادة تسليم طلب افتراضي؛ لم يُبنَ مستهلك متصل بخدمة خارجية ولم تُرسل أحداث حقيقية.

مقالات ذات صلة

الخدمة المرتبطة: تطوير المشاريع البرمجية الجامعية.

أرسل متطلبات مشروعك