Skip to content

Класс FlagEvaluator

Правила разрешения значения флага по элементу снимка конфигурации. Состояния не хранит, поэтому один экземпляр обслуживает любое число оценок.

Тот же класс используется сервером OneFlag. Общий код исключает расхождение между тем, что показывает дашборд, и тем, что видит приложение.

Исходник: src/Классы/FlagEvaluator.os

Конструктор

bsl
Новый FlagEvaluator()

Параметров нет.

ОценитьПоСнимку

bsl
Функция ОценитьПоСнимку(Знач Ключ, Знач Настройка, Знач Контекст = Неопределено,
	Знач ЗначениеПоУмолчанию = Неопределено) Экспорт

Разрешает значение флага по его настройке в окружении.

Параметры

ПараметрТипНазначение
КлючСтрокаКлюч флага. Участвует в хешировании процентной выкатки
НастройкаСоответствиеЭлемент снимка конфигурации
КонтекстСоответствиеАтрибуты пользователя, включая targetingKey
ЗначениеПоУмолчаниюПроизвольныйЗначение при внештатной ситуации

Поля Настройка:

ПолеТипНазначение
включенБулевоФлаг включён в окружении
вариантыСоответствиеИмя варианта → значение
вариантПоУмолчаниюСтрокаВариант, когда правила не сработали
процентВыкаткиЧислоДоля аудитории, 100 по умолчанию
правилаМассивПравила таргетинга, проверяются по порядку

Возвращаемое значение

Соответствие с полями:

ПолеТипСодержимое
значениеПроизвольныйЗначение варианта либо ЗначениеПоУмолчанию
вариантСтрокаИмя выбранного варианта, пустая строка при отказе
причинаСтрокаSTATIC, TARGETING_MATCH, SPLIT, DISABLED или ERROR
кодОшибкиСтрокаКод ошибки OpenFeature, пустая строка при успехе

Порядок разрешения

  1. Настройка не передана - ERROR с кодом FLAG_NOT_FOUND;
  2. включен не равно Истина - значение по умолчанию, причина DISABLED;
  3. сработало правило таргетинга - вариант правила, причина TARGETING_MATCH;
  4. процентВыкатки не меньше 100 - вариант по умолчанию, причина STATIC;
  5. в контексте нет непустого targetingKey - ERROR с кодом TARGETING_KEY_MISSING;
  6. пользователь не попал в выкатку - значение по умолчанию, причина SPLIT;
  7. иначе вариант по умолчанию, причина SPLIT.

Без targetingKey процентная выкатка была бы случайной при каждом вызове, поэтому она не выполняется, а не выбирает наугад. Попадание считается через bucketer от пары «ключ флага + ключ таргетинга»: один и тот же пользователь всегда попадает в тот же бакет, поэтому при увеличении процента никто не выключается обратно.

Если варианты отсутствуют или названного варианта в них нет - ERROR с кодом PARSE_ERROR.

Правило таргетинга

json
{ "атрибут": "plan", "оператор": "равно", "значения": ["pro"], "вариант": "вкл" }
ПолеНазначение
атрибутИмя атрибута контекста. Отсутствующий атрибут правило пропускает
операторСм. таблицу ниже. По умолчанию равно
значенияМассив эталонов. Пустой массив правило не выбирает
вариантИмя варианта при срабатывании

Правила проверяются по порядку, срабатывает первое подошедшее.

Операторы

ОператорУсловие
равноЗначение атрибута совпадает с одним из эталонов
не равноЗначение атрибута не совпадает ни с одним эталоном
содержитЭталон входит в значение как подстрока
начинается сЗначение начинается с эталона
заканчивается наЗначение заканчивается эталоном
больше, меньшеЧисловое сравнение
версия равна, версия больше, версия меньшеСравнение по semver
версия в диапазонеВхождение в диапазон semver

Нечисловое значение числовые операторы не выбирают, а не роняют оценку. То же с версиями: значение или эталон, которые версией не разбираются, правило не выбирает.

Диапазон принимает форму >=1.2.0, ^1.2.3, ~1.2, 1.2.x или составную >=1.0.0 <2.0.0. Составной диапазон собирается по частям: Версии.ВерсияВДиапазоне читает из строки только первое условие и молча отбрасывает остальные, из-за чего 5.0.0 прошла бы проверку >=1.0.0 <2.0.0. Пустой эталон диапазона считается ошибкой настройки и правило не выбирает, хотя semver трактовал бы его как *.

bsl
Оценщик = Новый FlagEvaluator();

Настройка = Новый Соответствие();
Настройка.Вставить("включен", Истина);
Настройка.Вставить("варианты", Новый Соответствие());
Настройка["варианты"].Вставить("вкл", Истина);
Настройка["варианты"].Вставить("выкл", Ложь);
Настройка.Вставить("вариантПоУмолчанию", "выкл");
Настройка.Вставить("процентВыкатки", 100);

Контекст = Новый Соответствие();
Контекст.Вставить("targetingKey", "user-42");

Оценка = Оценщик.ОценитьПоСнимку("new-checkout", Настройка, Контекст, Ложь);

Сообщить(Оценка["значение"]);   // Ложь
Сообщить(Оценка["вариант"]);    // выкл
Сообщить(Оценка["причина"]);    // STATIC