Когда фича-флаги становятся техническим долгом
Вы выкатили новую фичу через фича-флаг. Она сработала. Пользователи её приняли. Флаг включён для всех. Прошли месяцы. Теперь этот флаг всё ещё в коде, рядом с тремя другими флагами с прошлого квартала, двумя — полугодовой давности и одним, который никто уже не помнит, за что отвечает.
Это не редкость. Многие команды начинают использовать фича-флаги с благими намерениями: безопасные релизы, постепенные выкатки, аварийные рубильники. Но флаги, которые никогда не удаляются, постепенно превращаются в проблему другого рода. Они перестают быть инструментом управления релизами и становятся техническим долгом, замедляющим всех.
Реальная цена забытых флагов
Каждый оставленный в коде флаг добавляет точку принятия решения. Когда разработчик читает функцию, он вынужден спрашивать: эта ветка ещё используется? Эту можно безопасно удалить? Могу ли я удалить старый путь кода, или какой-то пользователь всё ещё по нему ходит?
С одним-двумя флагами это терпимо. С десятками чтение кода превращается в угадайку. Вы получаете if-else блоки, где никто не уверен, какой путь активен. Код, который когда-то был прямолинейным, превращается в лабиринт условной логики, к которому все боятся прикасаться.
Есть и затраты на исполнение. Каждый раз, когда приложение запускается, оно вычисляет каждый флаг. Одна проверка флага стоит дёшево. Сотни проверок в горячих участках кода накапливаются. Тактовые циклы CPU, потраченные на вычисление флагов, которые всегда возвращают одно и то же значение, тратятся впустую. Память, используемая для хранения конфигураций флагов, которые никогда не меняются, тратится впустую. Со временем эти накладные расходы становятся измеримыми, особенно в высоконагруженных сервисах.
Каждому флагу нужен жизненный цикл
Решение — не переставать использовать фича-флаги. Решение — относиться к каждому флагу как к тому, что в конечном итоге должно быть удалено. Фича-флаг должен иметь чёткий жизненный цикл с момента создания:
Следующая диаграмма показывает предполагаемый жизненный цикл фича-флага и что происходит, если удаление пропущено:
- Флаг добавляется, когда начинается работа над новой фичей.
- Он включается для внутреннего тестирования.
- Он постепенно выкатывается на подмножество пользователей.
- Он включается для всех пользователей.
- Фича проверяется как стабильная в продакшене.
- Флаг удаляется.
Шаг шестой — тот, который большинство команд пропускает. Фича работает. Все её используют. Флаг всё ещё включён, так зачем его удалять? Потому что каждый день, когда флаг остаётся, он добавляет трения. Код становится труднее читать. Следующее изменение занимает больше времени. Риск внесения ошибки возрастает, потому что никто не уверен, какие пути кода на самом деле активны.
Когда удалять флаг
Правильное время для удаления флага — как только фича, которую он контролирует, стабильна и полностью выкачена. Некоторые команды устанавливают жёсткое правило: удалить флаг в течение одного-двух спринтов после того, как фича достигла 100% пользователей. Другие используют автоматические напоминания, которые помечают любой ключ конфигурации, активный сверх определённого периода.
Удаление флага — это не просто удаление условной проверки. Вам также нужно очистить старый код, который флаг защищал. Если новая фича заменила старую, удалите старый путь кода целиком. Не оставляйте мёртвый код. Мёртвый код не безвреден. Он сбивает с толку разработчиков, тратит время сборки и может вызывать тонкие ошибки, если кто-то позже изменит его, думая, что он всё ещё используется.
Со стороны конфигурации также удалите флаг из вашей системы управления флагами. Флаг, удалённый из кода, но всё ещё видимый в дашборде или конфигурационном файле, вызовет путаницу. Кто-нибудь в конце концов спросит, нужен ли ещё этот флаг, и никто не даст чёткого ответа.
Сделайте удаление частью процесса
Самый эффективный способ предотвратить накопление флагов — требовать план удаления при создании флага. Когда разработчик открывает pull request, добавляющий новый фича-флаг, PR должен включать заметку о том, когда и как флаг будет удалён. Это может быть комментарий в коде, задача в вашем инструменте управления проектами или автоматическая дата истечения в самой системе флагов.
Некоторые команды идут дальше и обеспечивают истечение срока действия флагов программно. Система флагов отклоняет любой новый флаг, который не включает обязательную дату истечения. Когда дата проходит, система отправляет уведомление или даже автоматически отключает флаг. Это вынуждает команду либо удалить флаг, либо явно продлить его срок с обоснованием.
Это может звучать как излишняя нагрузка для небольшой команды, выпускающей одну фичу в месяц. Но этот паттерн масштабируется. Как только у вас несколько команд, выпускающих несколько фич параллельно, ручное управление флагами становится неустойчивым. Дисциплина, которую вы выстроите рано, избавит вас от болезненной уборки позже.
Практический чеклист для очистки флагов
Если вы хотите начать очистку флагов уже сегодня, вот простой процесс:
- Определите все флаги, присутствующие в вашей кодовой базе и системе конфигурации.
- Для каждого флага определите, полностью ли выкачена и стабильна ли фича, которую он контролирует.
- Если фича стабильна, удалите флаг из кода и удалите старый путь кода.
- Удалите флаг из вашей системы конфигурации или управления флагами.
- Обновите любую документацию или runbook'и, которые ссылаются на флаг.
- Для любого нового флага добавьте план удаления в pull request, который его вводит.
Это не разовое упражнение. Сделайте это регулярной практикой. Некоторые команды выделяют один спринт в квартал на очистку флагов. Другие добавляют это в своё определение готовности для каждой фичи. Найдите ритм, который работает для вашей команды, и придерживайтесь его.
Суть
Фича-флаги — мощный инструмент для управления релизами и снижения рисков. Но они не бесплатны. Каждый флаг, который вы держите дольше его полезного срока, добавляет сложность, замедляет разработку и увеличивает вероятность ошибок. Цель — не избегать флагов. Цель — использовать их дисциплинированно и удалять, когда они выполнили свою задачу.
Если вы позволите флагам накапливаться, они перестанут быть механизмом управления релизами и станут бременем, которое ваша команда несёт каждый день. Очистите их. Ваше будущее «я» и разработчик, которому придётся читать ваш код в следующем месяце, скажут вам спасибо.