Причина - збережені значення. Драйвер database при першій перевірці обчислює прапорець для скопу і записує результат у таблицю features. Далі Pennant читає збережене значення, а замикання з визначенням не викликається.
Сценарій: прапорець new-checkout визначено як Lottery::odds(1 / 10). Через тиждень команда змінює його на true для всіх - але 90% користувачів, яким раніше випало false, так і бачать стару версію.
Як оновити вже збережені значення:
Feature::activateForEveryone('new-checkout'); // усім true
Feature::deactivateForEveryone('new-checkout'); // усім false
Feature::purge('new-checkout'); // видалити збережене - наступна перевірка обчислить заново
php artisan pennant:purge new-checkout
Продуктивність:
- кеш у пам'яті: у межах запиту значення кешується, тож повторні перевірки не йдуть у базу;
- цикли: перевірка прапорця для кожного з сотні користувачів - сотня запитів. Рішення - жадібне завантаження:
Feature::for($users)->load(['notifications-beta']);
- драйвер
arrayне зберігає нічого між запитами - для тестів (PENNANT_STORE=array) або для прапорців, які завжди обчислюються з даних; - власний драйвер - якщо прапорці керуються зовнішнім сервісом (LaunchDarkly, Unleash) чи конфігурацією.
Класові прапорці зручніші за замикання для великих проєктів: окремий клас з методом resolve, автоматичне визначення, впровадження залежностей, а ім'я класу - ідентифікатор, який легко знайти пошуком по коду.
Життєвий цикл прапорця:
- створення з власником і очікуваною датою видалення;
- поступовий запуск і моніторинг помилок та метрик;
- повний запуск -
activateForEveryone; - прибирання: видалити перевірки й стару гілку коду, визначення прапорця,
purgeзбережених значень.
Чому прибирання - найважливіше: кожен активний прапорець подвоює кількість шляхів виконання. Десять прапорців - потенційно тисяча комбінацій, які ніхто не тестує. Корисні практики: список прапорців з датами в README чи задачах, нагадування в CI для прапорців, старших за N тижнів, тести для обох станів кожного прапорця.
Не плутати з конфігурацією: прапорці - тимчасовий механізм для запуску. Постійні налаштування клієнтів (тарифні можливості) краще моделювати явно - через план підписки чи налаштування тенанта.