Skip to content

Repository files navigation

openfeature

telegram chatAsk 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 фича-флагов: клиент, провайдеры, контекст оценки и хуки

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages