Skip to content

Repository files navigation

openfeature

OpenYellow telegram chat Ask DeepWiki

Реализация OpenFeature - открытого стандарта CNCF для оценки фича-флагов - на OneScript.

Прикладной код работает с флагами через единый API и ничего не знает о том, где они хранятся. Систему управления флагами можно заменить, поменяв одну строку регистрации провайдера: локальный JSON на старте, свой сервер в проде, набор в памяти в тестах.

Установка

opm install openfeature

Использование

Настройка и оценка

#Использовать openfeature

// Один раз при старте приложения
OpenFeature.УстановитьПровайдер(Новый JsonFileProvider("flags.json"));

// Дальше везде
Клиент = OpenFeature.ПолучитьКлиента();

Если Клиент.ПолучитьЛогическое("new-checkout", Ложь) Тогда
    ПоказатьНовуюКорзину();
КонецЕсли;

Оценка никогда не выбрасывает исключений. Недоступный провайдер, отсутствующий флаг, неверный тип значения - во всех случаях вернётся переданное значение по умолчанию. Флаги не должны ронять приложение.

Таргетинг

Контекст = Новый EvaluationContext("user-42", Новый Структура("plan", "pro"));

Тема = Клиент.ПолучитьСтроку("тема", "light", Контекст);

Ключ таргетинга - идентификатор субъекта оценки: по нему провайдеры закрепляют пользователя за вариантом, чтобы процентные выкатки были стабильными.

Контекст уровня приложения задаётся один раз и объединяется с контекстом вызова, причём контекст вызова имеет приоритет:

OpenFeature.УстановитьГлобальныйКонтекст(Новый EvaluationContext("", Новый Структура("окружение", "prod")));

Подробности оценки

Детали = Клиент.ПолучитьСтрокуСДеталями("тема", "light", Контекст);

Сообщить(Детали.Значение);    // dark
Сообщить(Детали.Вариант);     // тёмная
Сообщить(Детали.Причина);     // TARGETING_MATCH
Сообщить(Детали.КодОшибки);   // пусто при успехе

Описание флагов

Провайдеры InMemoryProvider и JsonFileProvider понимают два вида описания. Простое - сразу значение:

{
  "new-checkout": true,
  "максимум-позиций": 25
}

Развёрнутое - с вариантами и правилами таргетинга:

{
  "тема": {
    "Варианты": { "светлая": "light", "тёмная": "dark" },
    "ВариантПоУмолчанию": "светлая",
    "Правила": [
      { "Атрибут": "plan", "Значения": ["pro", "enterprise"], "Вариант": "тёмная" }
    ]
  },
  "выключенный": { "Значение": true, "Включен": false }
}

Правила проверяются по порядку, побеждает первое совпавшее; если ни одно не сработало, берётся вариант по умолчанию. Выключенный флаг всегда отдаёт значение по умолчанию с причиной DISABLED.

В коде набор флагов удобнее задавать Соответствием: ключи флагов обычно содержат дефис, а Структура такие имена не допускает.

Флаги = Новый Соответствие();
Флаги.Вставить("new-checkout", Истина);

OpenFeature.УстановитьПровайдер(Новый InMemoryProvider(Флаги));

Хуки

Хук - объект с методами До, После, ПриОшибке, Финально; реализовать можно любое подмножество.

Функция До(Знач Данные, Знач Подсказки) Экспорт
    // Можно дополнить контекст - возвращённые атрибуты имеют приоритет
    Возврат Новый EvaluationContext("", Новый Структура("окружение", "prod"));
КонецФункции

Процедура После(Знач Данные, Знач Детали, Знач Подсказки) Экспорт
    Метрики.Учесть(Данные.КлючФлага, Детали.Вариант);
КонецПроцедуры
OpenFeature.ДобавитьХук(Новый ХукМетрик());   // для всех клиентов
Клиент.ДобавитьХук(Новый ХукАудита());        // для одного клиента

Стадия До выполняется от глобальных хуков к локальным, а После, ПриОшибке и Финально - в обратном порядке. Сбой хука не роняет оценку: она завершается штатным отказом со значением по умолчанию.

Публичный API

Модуль OpenFeature

Метод Возвращает Описание
УстановитьПровайдер(Провайдер) - Регистрирует провайдера, инициализирует его и завершает предыдущего
ПолучитьКлиента(Домен = "") FeatureClient Клиент оценки
ДобавитьХук(Хук) - Хук для всех клиентов
УстановитьГлобальныйКонтекст(Контекст) - Контекст уровня приложения
ГлобальныйКонтекст() EvaluationContext Текущий глобальный контекст
Провайдер() / МетаданныеПровайдера() / СостояниеПровайдера() Сведения о провайдере
Завершить() - Сброс всего состояния API
СоздатьИзолированныйЭкземпляр() OpenFeatureApi Независимый экземпляр API

Класс FeatureClient

ПолучитьЛогическое, ПолучитьСтроку, ПолучитьЧисло, ПолучитьОбъект и их варианты …СДеталями. Сигнатура: (Ключ, ЗначениеПоУмолчанию, Контекст = Неопределено, Параметры = Неопределено), где Параметры - структура с полями Хуки и ПодсказкиХуков.

Также ДобавитьХук(Хук), Метаданные(), СостояниеПровайдера().

Класс EvaluationContext

КлючТаргетинга(), УстановитьКлючТаргетинга(Значение), Установить(Имя, Значение), Получить(Имя, ЗначениеПоУмолчанию), Содержит(Имя), Атрибуты(), Объединить(Другой), Количество().

Класс EvaluationDetails

Свойства КлючФлага, Значение, Вариант, Причина, КодОшибки, СообщениеОбОшибке, МетаданныеФлага; методы ЭтоОшибка(), Метаданное(Имя, ЗначениеПоУмолчанию).

Модули OpenFeatureReason и OpenFeatureErrorCode

Константы вместо строковых литералов: OpenFeatureReason.СовпадениеТаргетинга()TARGETING_MATCH, OpenFeatureErrorCode.ФлагНеНайден()FLAG_NOT_FOUND и так далее.

Свой провайдер

Провайдер - объект со следующими методами:

Функция Метаданные() Экспорт                     // Структура("Имя", "МойПровайдер")
Процедура Инициализировать(Знач Контекст) Экспорт
Процедура Завершить() Экспорт
Функция Состояние() Экспорт                      // NOT_READY, READY, ERROR, STALE, FATAL

Функция ВычислитьЛогическое(Знач Ключ, Знач ЗначениеПоУмолчанию, Знач Контекст) Экспорт
Функция ВычислитьСтроку(Знач Ключ, Знач ЗначениеПоУмолчанию, Знач Контекст) Экспорт
Функция ВычислитьЧисло(Знач Ключ, Знач ЗначениеПоУмолчанию, Знач Контекст) Экспорт
Функция ВычислитьОбъект(Знач Ключ, Знач ЗначениеПоУмолчанию, Знач Контекст) Экспорт

Каждый метод оценки возвращает ResolutionDetails:

Функция ВычислитьЛогическое(Знач Ключ, Знач ЗначениеПоУмолчанию, Знач Контекст) Экспорт

    Если НеНашли(Ключ) Тогда
        Результат = Новый ResolutionDetails(ЗначениеПоУмолчанию);
        Возврат Результат.ЗаполнитьОшибку(OpenFeatureErrorCode.ФлагНеНайден(),
            "Флаг не найден", ЗначениеПоУмолчанию);
    КонецЕсли;

    Возврат Новый ResolutionDetails(Значение, OpenFeatureReason.СовпадениеТаргетинга(), "вариант-а");

КонецФункции

Соответствие спецификации

Реализованы обязательные требования разделов Flag Evaluation, Providers, Evaluation Context и Hooks:

  • API - глобальный синглтон; есть и фабрика изолированных экземпляров (раздел 1.8).
  • Регистрация провайдера вызывает Инициализировать у нового и Завершить у предыдущего.
  • До регистрации провайдера работает заглушка, возвращающая значения по умолчанию с причиной DEFAULT.
  • Клиент не выбрасывает исключений и гарантирует тип: значение неожиданного типа заменяется значением по умолчанию с кодом TYPE_MISMATCH.
  • EvaluationDetails содержит ключ флага, значение, вариант, причину, код и сообщение об ошибке; поле метаданных при отсутствии данных - пустая запись, а не Неопределено.
  • Причины и коды ошибок соответствуют перечням спецификации.
  • Порядок стадий хуков и слияние контекстов - по спецификации; ошибка в хуке приводит к штатному отказу оценки.

Не реализовано в этой версии: события провайдера (PROVIDER_READY, PROVIDER_CONFIGURATION_CHANGED и прочие), транзакционный контекст, доменные провайдеры (ПолучитьКлиента("домен") возвращает клиент с метаданными домена, но привязка отдельного провайдера к домену не поддерживается), tracking API.

Тесты

opm install -l
oneunit execute -d ./tests

Лицензия

MIT

About

Стандартный API фича-флагов: клиент, провайдеры, контекст оценки и хуки

Topics

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages