CI/CD / السلامة والتنسيق والتحسين / الدرس 15
التزامن والإصدارات القديمة وإعادة آمنة
امنع تداخل التبني وافهم العملية ذات الاكتمال غير المؤكد.
في هذه الصفحة
أهداف الدرس
- فصل الاستبعاد المتبادل عن ترتيب الإصدارات.
- نمذجة الطلب المكرر والقديم دون آثار فعلية.
القفل لا يثبت الحداثة
قد ينتهي اختبار مرشحي Parcel بترتيب مخالف لمراجعات المصدر. قد يصل r9 أولاً ويتبعه r8 الأبطأ. تمنع السلسلة التداخل لكنها قد تثبت الأقدم أخيراً. حدد الاستبعاد والترتيب أو الحداثة معاً. يجيب القفل عمن يتصرف الآن ولا يقرر بقاء ملاءمة المنتظر. استخدم تنسيقاً خاصاً بالهدف وتجنب قفلاً عاماً يمنع بيئات مستقلة بلا داعٍ.
اختر سلوك الطابور عمداً
تحتفظ أنظمة بكل إصدار منتظر وأخرى تستبدله أو تقدم الأحدث. ليست سياسة مناسبة دائماً. يختلف ترحيل يحتاج كل انتقال عن خدمة بلا حالة تتخطى الوسيط. تختلف آليات التزامن أيضاً فلا تفترض FIFO. وثق المرشحين الممكن تجاوزهم وتفاعل الإلغاء مع عمل خارجي مقبول. يوضح التسلسل التالي كيف تتراجع البيئة رغم التسلسل.
r8 starts tests
r9 starts and finishes tests
r9 adopts under target lock
r8 later acquires lock -> must recheck freshness
الخط الزمني افتراضي. يجب أن يستشير الفحص النهائي سياسة أو حالة مرجعية، ولا تُرتب أسماء المصدر كنصوص لاستنتاج الزمن.
يحتاج تكرار الطلب هوية ثابتة
تكون العملية آمنة التكرار ضمن عقدها عندما يعطي تكرارها الأثر المقصود نفسه لتطبيق واحد. قد يعيد العميل بعد مهلة رغم قبول الطلب الأول. استخدم هوية عملية ثابتة ومنع تكرار لدى الهدف حيث يدعم، ثم افحص النتيجة المسجلة. يهزم معرف عشوائي جديد في كل محاولة إزالة التكرار. لا تصف نص صدفة بالآمن لمجرد أنه خرج بصفر مرتين غالباً.
ارفض المكرر والجيل الأقدم
يستخدم النموذج الكامل أجيالاً صحيحة كترتيب معلن. يسجل هويات الطلب ويرفض الأقدم ويتجنب إعادة الناجح. هو أبسط عمداً من التنسيق الموزع: لا معاملة قاعدة ولا عامل متزامن ولا رمز تسييج ولا تعافي انهيار. يجب على المتحكم الحقيقي جعل القبول والتغيير ذريين بضمانات منصته. يوضح النموذج الثوابت دون ادعاء حل تسابق موزع بقاموس.
current = 9
seen = set()
def adopt(request_id, generation):
global current
if request_id in seen:
return "duplicate"
if generation < current:
return "stale"
current = generation
seen.add(request_id)
return "accepted"
print(adopt("request-a", 8))
print(adopt("request-b", 10))
print(adopt("request-b", 10))
stale
accepted
duplicate
تنتج القيم من ترتيب صحيح معلن واستدعاءات متسلسلة. لا يقدم البرنامج قفلاً موزعاً ولا تنفيذاً إنتاجياً لمنع التكرار.
لاحظ قبل إعادة العمل المجهول
عند مهلة الترقية ميّز الرفض والقبول الجاري والاكتمال بلا تقرير والمجهول. اقرأ دليلاً مرجعياً من الهدف بالمسار الموافق قبل الإعادة. قد يوقف إلغاء مهمة CI العميل دون الطرح الخارجي. يحتاج التنظيف ملكية أيضاً؛ لا تحذف مهمة ملغاة مورداً صار لطلب آخر. تجعل انتقالات الحالة والسجلات الدائمة والتعويض المحدود التعافي مفهوماً، بينما قد تحول إعادة عمياء غموضاً واحداً لتغييرين متعارضين.
الأخطاء الشائعة وإصلاحها
يستبدل الأقدم الأحدث رغم القفل.
- لماذا يحدث؟
- اختلط الاستبعاد بسياسة الحداثة.
- كيف تصلحه؟
- أعد فحص الأهلية بحالة مرجعية بعد حيازة التنسيق.
- كيف تتجنب تكراره؟
- وثق الترتيب والتجاوز والانتقالات المطلوبة.
تستخدم كل إعادة معرفاً جديداً.
- لماذا يحدث؟
- لا يستطيع الهدف تمييز النية المكررة.
- كيف تصلحه؟
- احتفظ بالهوية وافحص نتيجتها المسجلة.
- كيف تتجنب تكراره؟
- صمم الهوية ومنع التكرار معاً.
يُفترض أن إلغاء CI يلغي التبني الخارجي.
- لماذا يحدث؟
- اختلط عمر العميل بعمر عملية الهدف.
- كيف تصلحه؟
- لاحظ العملية واستخدم إلغاءها المدعوم إذا صُرح به.
- كيف تتجنب تكراره؟
- حدد الإلغاء والتنظيف قبل الإصدار.
اختبر فهمك
1. يمكن لخدمة بلا حالة تخطي المرشحين. هل تنشر كل المنتظرين؟
اعرض الحل المشروح
ليس بالضرورة. قد تستبدل سياسة أحدث مؤهل مراجعة المرشحين المنتظرين مع بقاء الأدلة والتوافق. تحقق من دلالات الانتظار والإلغاء الفعلية، ولا تطبق الاختصار على ترحيل يحتاج ترتيباً.
2. قبل الهدف request-b وفُقد الرد. ماذا تفعل الإعادة؟
اعرض الحل المشروح
تستخدم الهوية نفسها وتستعلم أو تعيد وفق عقد منع التكرار. فرّق المكتمل والجاري والغائب. إن لم يوجد عقد فحقق الحالة قبل تكرار الأثر ولا تفترض أن المهلة تعني عدم حدوثه.
أهم ما تعلمته
- نسّق التداخل والحداثة كثابتين منفصلين.
- يحتاج الغموض ملاحظة وهوية إعادة ثابتة.