عندما تتحول أعلام الميزات إلى ديون تقنية
لقد كنت تُصدر الميزات باستخدام أعلام الميزات (Feature Flags) لمدة ستة أشهر. كل قدرة جديدة تحصل على علمها الخاص. بعض الميزات انتهى اختبارها منذ أسابيع وأصبحت متاحة الآن لكل مستخدم. لكن الأعلام لا تزال موجودة في الكود. الآن أصبحت قاعدة الكود مليئة بالفروع الشرطية التي لا يتذكرها أحد. ينضم مطور جديد إلى الفريق، ويفتح ملفًا، ويرى خمسة فحوصات مختلفة للأعلام. أي منها لا يزال نشطًا؟ أي منها يمكن إزالته؟ لا أحد يعرف.
هذه هي التكلفة الخفية لأعلام الميزات. إنها أدوات قوية للتسليم التدريجي، لكنها تأتي مع تاريخ انتهاء صلاحية تتجاهله الفرق غالبًا. نفس الآلية التي تتيح لك الإصدار الآمن يمكن أن تصبح عبئًا صيانويًا إذا لم تخطط لإزالتها.
لماذا تتراكم الأعلام
تبدأ المشكلة ببراءة. يحتاج الفريق إلى التحكم في الوصول إلى ميزة جديدة أثناء الاختبار. يضيفون علمًا. تعمل الميزة، لذا يقومون بنشرها لمزيد من المستخدمين. ثم ينتقلون إلى المشروع التالي. يبقى العلم في الكود لأن إزالته تبدو وكأنها عمل إضافي بدون فائدة فورية.
بمرور الوقت، تمتلئ قاعدة الكود بشروط ميتة. تزداد ملفات التهيئة طولاً. تظهر لوحات المنصة عشرات الأعلام، لكن نصفها مفعل بشكل دائم. كل نشر يحمل تعقيدًا غير ضروري. عندما يحدث عطل، يضيع المطورون وقتًا في تتبع منطق الأعلام الذي لم يعد مهمًا.
السبب الجذري بسيط: تركز الفرق على إنشاء وتفعيل الأعلام لكنها تنسى أن لكل علم دورة حياة. يولد العلم، ويؤدي غرضه، ثم يجب أن يموت. بدون خطة لهذه الخطوة النهائية، تتحول الأعلام إلى ديون تقنية تتراكم مع كل إصدار.
دورة حياة علم الميزة
يمر علم الميزة الصحي بمراحل واضحة. يبدأ عندما يقرر الفريق إنشائه. في تلك اللحظة، يجب على شخص ما تسجيل غرض العلم: أي ميزة يتحكم بها، ومن يمكنه تبديلها، ومتى يجب إزالتها. قد تبدو هذه البيانات الوصفية وكأنها عبء إضافي، لكنها تصبح أساسية بعد أسابيع عندما يحتاج الفريق إلى تحديد الأعلام التي يجب تنظيفها.
بعد الإنشاء، ينتقل العلم عبر مراحل النشر. أولاً، يُفعّل الميزة للاختبار الداخلي. ثم لنسبة صغيرة من المستخدمين. ثم للجميع. في المرحلة النهائية، لم تعد الميزة تجريبية. إنها جزء من التطبيق. لا يوجد سبب لوجود العلم.
هنا يخفق معظم الفرق. يصلون إلى مرحلة "جميع المستخدمين" ويتوقفون عن التفكير في العلم. الميزة تعمل. ينتقل الفريق. يبقى العلم في الكود، مضيفًا تعقيدًا بصمت.
يلخص الرسم البياني التالي المراحل الأربع الرئيسية والإجراءات التي تنقل العلم من مرحلة إلى التالية.
ممارستان تمنعان تعفن الأعلام
منع تراكم الأعلام يتطلب شيئين: عملية تنظيف مجدولة وطريقة لاكتشاف الأعلام القديمة.
جدولة التنظيف في دورة التطوير الخاصة بك
اجعل إزالة العلم جزءًا منتظمًا من سير عملك. في نهاية كل سباق (Sprint)، راجع قائمة الأعلام التي كانت نشطة لجميع المستخدمين لأكثر من أسبوعين. قم بإزالة تلك الأعلام من الكود ومن منصة إدارة الأعلام الخاصة بك. إذا لم يمكن إزالة علم لأنه لا يزال مطلوبًا للاختبار A/B أو لميزة غير مكتملة، قم بتحديث بياناته الوصفية بتاريخ إزالة متوقع جديد.
هذا يبدو بسيطًا، لكنه يتطلب انضباطًا. الفرق التي تتخطى هذه الخطوة لسباق واحد غالبًا ما تتخطاها للسباق التالي. قبل مضي وقت طويل، ينمو backlog التنظيف ليصبح أكبر مما يرغب أي شخص في معالجته.
الكشف عن الأعلام القديمة تلقائيًا
المراجعات اليدوية ليست كافية. أنت بحاجة إلى كشف تلقائي. العديد من منصات أعلام الميزات يمكنها وضع علامة على الإدخالات التي لم يتم تعديلها أو فحصها خلال فترة معينة. إذا كانت منصتك لا تدعم ذلك، اكتب سكريبت بسيطًا يقرأ تهيئة العلم ويقارنها بآخر طابع زمني للتعديل. الأعلام التي لم يتم لمسها لأسابيع والمفعلة لجميع المستخدمين هي مرشحة رئيسية للإزالة.
تذهب بعض الفرق إلى أبعد من ذلك وتضيف خطوة فحص (Linting) إلى خط أنابيب CI الخاص بها. يفحص المدقق (Linter) الأعلام التي كانت في قاعدة الكود لفترة أطول من حد مُهيأ ويحذر المطور. هذا يلتقط الأعلام القديمة قبل أن تصبح تركيبات دائمة.
على سبيل المثال، يبحث السكريبت التالي عن اسم علم في الكود المصدري ويستعلم عن API إدارة الأعلام لمعرفة ما إذا كان مفعلًا بشكل دائم لجميع المستخدمين:
#!/bin/bash
FLAG_NAME="MY_FLAG"
# عد مرات الظهور في الكود المصدري
OCCURRENCES=$(grep -r "$FLAG_NAME" src/ --include='*.js' | wc -l)
# استعلام عن حالة العلم من API الإدارة
STATUS=$(curl -s "https://flags.example.com/api/flags/$FLAG_NAME" | jq -r '.status')
# إذا كان العلم مفعلًا بشكل دائم ونادرًا ما يُشار إليه، ضع علامة عليه
if [ "$STATUS" = "permanently_enabled" ] && [ "$OCCURRENCES" -gt 0 ]; then
echo "تحذير: العلم $FLAG_NAME مفعل بشكل دائم لكنه لا يزال مستخدمًا في $OCCURRENCES مكانًا."
echo "فكر في إزالته من الكود والتهيئة."
fi
لماذا التنظيف مهم يتجاوز نظافة الكود
تنظيف أعلام الميزات لا يتعلق فقط بالحفاظ على قاعدة الكود مرتبة. يتعلق بالحفاظ على ثقة الفريق في النظام. عندما يكون المطورون غير متأكدين مما إذا كان العلم لا يزال قيد الاستخدام، يصبحون خائفين من إزالته. يقلقون من أن بعض التبعيات غير المعروفة قد تنكسر. لذا يبقى العلم، ويصبح التهيئة أكثر تعقيدًا. كلما طالت مدة بقائه، زادت صعوبة إزالته، لأنه لا يمكن لأحد تتبع جميع الأماكن التي قد يكون مهمًا فيها.
هذا التآكل في الثقة له عواقب حقيقية. تستغرق الميزات الجديدة وقتًا أطول للتنفيذ لأن المطورين يجب أن يعملوا حول منطق الأعلام القديم. يصبح التصحيح أبطأ لأنه يجب تقييم كل فرع شرطي. يصبح دمج أعضاء الفريق الجدد أصعب لأنهم يجب أن يتعلموا تاريخ كل علم قبل أن يتمكنوا من المساهمة.
دورة حياة علم نظيفة تستعيد تلك الثقة. عندما يكون لكل علم غرض معروف وتاريخ إزالة مخطط له، يمكن للمطورين الوثوق بأن الكود الذي يرونه هو الكود المهم. يمكنهم حذف الأعلام دون خوف. يمكنهم التركيز على بناء ميزات جديدة بدلاً من فك رموز التجارب القديمة.
قائمة تحقق عملية لإدارة دورة حياة العلم
- سجل الغرض والمالك وتاريخ الإزالة المتوقع عند إنشاء علم جديد.
- راجع جميع الأعلام في نهاية كل سباق. قم بإزالة تلك النشطة لجميع المستخدمين لأكثر من أسبوعين.
- استخدم أدوات تلقائية لاكتشاف الأعلام التي لم يتم تعديلها أو فحصها مؤخرًا.
- أضف خطوة فحص (Linting) في CI تحذر بشأن الأعلام الأقدم من حد قابل للتهيئة.
- قم بتحديث البيانات الوصفية للعلم عندما يتغير تاريخ الإزالة. لا تدع التواريخ تنجرف دون اعتراف.
- قم بإزالة الأعلام من كل من الكود والتهيئة. العلم المتبقي في التهيئة لا يزال مسؤولية.
الخلاصة
أعلام الميزات ليست دائمة. عاملها كسقالات مؤقتة: ضعها عندما تحتاجها، وأزلها عندما يقف الهيكل بمفرده. العلم الذي يبقى في الكود بعد إصدار ميزته بالكامل ليس شبكة أمان. إنه وزن ميت. خطط للإزالة من اليوم الأول، وسيظل خط أنابيب التسليم التدريجي الخاص بك خفيفًا وسريعًا وجديرًا بالثقة.