عندما تتحول أعلام الميزات إلى ديون تقنية
لقد أطلقت ميزة جديدة باستخدام علم ميزة (Feature Flag). عملت الميزة. اعتمدها المستخدمون. بقي العلم مفعّلاً للجميع. مرت أشهر. الآن لا يزال هذا العلم موجودًا في الكود، بجانب ثلاثة أعلام أخرى من الربع الماضي، واثنين من ستة أشهر مضت، وواحد لا يتذكر أحد ما يتحكم به.
هذا ليس أمرًا غير معتاد. تبدأ العديد من الفرق باستخدام أعلام الميزات بنوايا حسنة: إصدارات أكثر أمانًا، طرح تدريجي، مفاتيح إيقاف للطوارئ. لكن الأعلام التي لا تُزال أبدًا تتحول ببطء إلى نوع مختلف من المشاكل. تتوقف عن كونها أداة للتحكم في الإصدار وتبدأ في أن تكون دينًا تقنيًا يبطئ الجميع.
التكلفة الحقيقية للأعلام المهجورة
كل علم تتركه في الكود يضيف نقطة قرار. عندما يقرأ المطور دالة، عليه أن يسأل: هل هذا الفرع لا يزال مستخدمًا؟ هل هذا الفرع آمن للإزالة؟ هل يمكنني حذف مسار الكود القديم، أم أن هناك مستخدمًا ما لا يزال يستخدمه؟
مع علم أو اثنين، هذا أمر يمكن التحكم به. مع العشرات، تصبح قراءة الكود لعبة تخمين. ينتهي بك الأمر بكتل if-else حيث لا أحد متأكد من أي مسار هو النشط. الكود الذي كان بسيطًا في السابق يتحول إلى متاهة من المنطق الشرطي الذي يخشى الجميع لمسه.
هناك أيضًا تكلفة وقت تشغيل. في كل مرة يعمل فيها التطبيق، يقوم بتقييم كل علم. فحص علم واحد رخيص. مئات فحوصات الأعلام في مسارات الكود الساخنة تتراكم. دورات المعالج التي تُستهلك في تقييم أعلام تعيد دائمًا نفس القيمة تُهدر. الذاكرة المستخدمة لتخزين تكوينات أعلام لا تتغير أبدًا تُهدر. بمرور الوقت، يصبح هذا العبء قابلاً للقياس، خاصة في الخدمات عالية الحركة.
كل علم يحتاج إلى دورة حياة
الحل ليس التوقف عن استخدام أعلام الميزات. الحل هو معاملة كل علم كشيء يجب إزالته في النهاية. يجب أن يكون لعلم الميزة دورة حياة واضحة منذ لحظة إنشائه:
يُظهر الرسم البياني التالي دورة الحياة المقصودة لعلم الميزة وما يحدث عند تخطي الإزالة:
- يُضاف العلم عند بدء العمل على ميزة جديدة.
- يتم تفعيله للاختبار الداخلي.
- يتم طرحه تدريجيًا لمجموعة فرعية من المستخدمين.
- يتم تفعيله لجميع المستخدمين.
- يتم التحقق من استقرار الميزة في الإنتاج.
- تتم إزالة العلم.
الخطوة السادسة هي التي تتخطاها معظم الفرق. الميزة تعمل. الجميع يستخدمها. العلم لا يزال مفعّلاً، فلماذا عناء إزالته؟ لأنه كل يوم يبقى فيه العلم، يضيف احتكاكًا. يصبح الكود أصعب في القراءة. التغيير التالي يستغرق وقتًا أطول. يزيد خطر إدخال خطأ لأنه لا أحد متأكد من مسارات الكود النشطة فعليًا.
متى يتم إزالة العلم
الوقت المناسب لإزالة العلم هو بمجرد أن تصبح الميزة التي يتحكم بها مستقرة ومطروحة بالكامل. تضع بعض الفرق قاعدة صارمة: إزالة العلم خلال سباق أو اثنين بعد وصول الميزة إلى 100% من المستخدمين. يستخدم آخرون تذكيرات آلية تضع علامة على أي مفتاح تكوين كان نشطًا لفترة تتجاوز حدًا معينًا.
إزالة العلم لا تتعلق فقط بحذف الفحص الشرطي. تحتاج أيضًا إلى تنظيف الكود القديم الذي كان العلم يحميه. إذا كانت الميزة الجديدة قد حلت محل ميزة قديمة، احذف مسار الكود القديم بالكامل. لا تترك كودًا ميتًا خلفك. الكود الميت ليس غير ضار. إنه يربك المطورين، ويضيع وقت البناء، ويمكن أن يسبب أخطاء دقيقة إذا قام شخص ما بتعديله لاحقًا معتقدًا أنه لا يزال قيد الاستخدام.
على جانب التكوين، قم بإزالة العلم من نظام إدارة الأعلام الخاص بك أيضًا. العلم الذي يتم حذفه من الكود ولكن لا يزال مرئيًا في لوحة التحكم أو ملف التكوين سيسبب ارتباكًا. سيسأل شخص ما في النهاية عما إذا كان هذا العلم لا يزال مطلوبًا، ولن يكون لدى أحد إجابة واضحة.
اجعل الإزالة جزءًا من العملية
الطريقة الأكثر فعالية لمنع تراكم الأعلام هي طلب خطة إزالة عند إنشاء العلم. عندما يفتح مطور طلب سحب (Pull Request) يضيف علم ميزة جديد، يجب أن يتضمن طلب السحب ملاحظة حول متى وكيف ستتم إزالة العلم. يمكن أن يكون هذا تعليقًا في الكود، أو مهمة في أداة إدارة المشروع، أو تاريخ انتهاء صلاحية تلقائي في نظام العلم نفسه.
تذهب بعض الفرق إلى أبعد من ذلك وتفرض انتهاء صلاحية العلم برمجيًا. يرفض نظام العلم أي علم جديد لا يتضمن تاريخ انتهاء صلاحية إلزاميًا. عندما يمر التاريخ، يرسل النظام إشعارًا أو حتى يعطل العلم تلقائيًا. هذا يجبر الفريق إما على إزالة العلم أو تمديد عمره بشكل صريح مع مبرر.
قد يبدو هذا وكأنه عبء إضافي لفريق صغير يصدر ميزة واحدة شهريًا. لكن النمط يتوسع. بمجرد أن يكون لديك فرق متعددة تصدر ميزات متعددة بالتوازي، تصبح إدارة الأعلام اليدوية غير مستدامة. الانضباط الذي تبنيه مبكرًا سيوفر عليك تنظيفًا مؤلمًا لاحقًا.
قائمة مهام عملية لتنظيف الأعلام
إذا كنت ترغب في البدء في تنظيف الأعلام اليوم، إليك عملية بسيطة:
- حدد جميع الأعلام الموجودة حاليًا في قاعدة الكود ونظام التكوين الخاص بك.
- لكل علم، حدد ما إذا كانت الميزة التي يتحكم بها مطروحة بالكامل ومستقرة.
- إذا كانت الميزة مستقرة، قم بإزالة العلم من الكود واحذف مسار الكود القديم.
- قم بإزالة العلم من نظام التكوين أو إدارة الأعلام الخاص بك.
- قم بتحديث أي وثائق أو أدلة تشغيل (runbooks) تشير إلى العلم.
- لأي علم جديد، أضف خطة إزالة في طلب السحب الذي يقدمه.
هذا ليس تمرينًا لمرة واحدة. اجعله ممارسة منتظمة. تخصص بعض الفرق سباقًا واحدًا كل ربع سنة لتنظيف الأعلام. يضيفه آخرون إلى تعريف "الإنجاز" (Definition of Done) لكل ميزة. ابحث عن إيقاع يناسب فريقك والتزم به.
الخلاصة
أعلام الميزات هي أداة قوية للتحكم في الإصدارات وتقليل المخاطر. لكنها ليست مجانية. كل علم تحتفظ به بعد عمره الإنتاجي يضيف تعقيدًا، ويبطئ التطوير، ويزيد من فرصة الأخطاء. الهدف ليس تجنب الأعلام. الهدف هو استخدامها بانضباط وإزالتها عندما تؤدي غرضها.
إذا تركت الأعلام تتراكم، فإنها تتوقف عن كونها آلية للتحكم في الإصدار وتصبح عبئًا يحمله فريقك كل يوم. نظفها. ذاتك المستقبلية، والمطور الذي سيقرأ كودك الشهر القادم، سيشكرونك.