Провайдер OpenFeature для сервера OneFlag: снимок конфигурации по HTTP, локальная оценка флагов и живое обновление по Server-Sent Events.
Приложение работает через стандартный API OpenFeature, поэтому не привязано к OneFlag: провайдера можно заменить, не трогая прикладной код.
opm install oneflag-sdk
#Использовать openfeature
#Использовать oneflag-sdk
OpenFeature.УстановитьПровайдер(
Новый OneFlagProvider("http://localhost:3333", "local-sdk-key", "prod"));
Клиент = OpenFeature.ПолучитьКлиента();
Контекст = Новый EvaluationContext("user-42", Новый Структура("plan", "pro"));
Если Клиент.ПолучитьЛогическое("new-checkout", Ложь, Контекст) Тогда
ПоказатьНовуюКорзину();
КонецЕсли;Переключение флага в дашборде OneFlag меняет поведение приложения в ту же секунду: перезапуск не нужен, опрос сервера не выполняется.
- При инициализации провайдер забирает снимок конфигурации одним запросом
GET /api/snapshot. - Дальше значения вычисляются локально: оценка флага не стоит сетевого вызова и работает при недоступном сервере.
- В фоновом задании читается поток
GET /stream; событие об изменении обновляет снимок. - Если сервер недоступен при старте, провайдер переходит в состояние
ERROR, а клиент OpenFeature отдаёт значения по умолчанию. Флаги не должны ронять приложение.
Правила разрешения значения вынесены в класс FlagEvaluator, который используется и на сервере OneFlag. Это исключает
расхождение между тем, что показывает дашборд, и тем, что видит приложение.
Операторы правил: равно, не равно, содержит, начинается с, заканчивается на, больше, меньше,
версия равна, версия больше, версия меньше, версия в диапазоне. Версии сравниваются по
semver, поэтому 1.10.0 новее 1.9.0, а 2.0.0-beta предшествует 2.0.0; диапазон принимает
форму >=1.2.0, ^1.2.3, ~1.2, 1.2.x или составную >=1.0.0 <2.0.0.
Конструктор: OneFlagProvider(Адрес, Ключ, Окружение = "dev", Настройки = Неопределено).
Необязательные Настройки - Структура или Соответствие:
| Параметр | По умолчанию | Описание |
|---|---|---|
ПовторовЗагрузки |
3 | Сколько раз повторить неудачный запрос снимка |
ЗадержкаПовтора |
500 | Пауза между попытками, мс |
ТаймаутЗапроса |
10 | Таймаут HTTP-запроса, с |
Повторы нужны, потому что первая неудача редко означает, что сервер недоступен: чаще это гонка при старте, когда приложение поднялось раньше сервиса флагов. Реализованы через resilience.
| Метод | Возвращает | Описание |
|---|---|---|
Инициализировать(Контекст = Неопределено) |
- | Загружает снимок и подписывается на изменения |
Завершить() |
- | Останавливает чтение потока и закрывает соединение |
Состояние() |
Строка |
NOT_READY, READY или ERROR |
ОбновитьСнимок() |
Булево |
Принудительно перечитывает конфигурацию |
ЖивоеОбновлениеРаботает() |
Булево |
Читается ли поток изменений |
КлючиФлагов() |
Массив |
Ключи известных флагов |
ПоследняяОшибка() |
Строка |
Описание последнего сбоя связи |
ОбновленийПолучено |
Число |
Сколько раз конфигурация обновлялась по потоку |
Методы контракта провайдера OpenFeature (ВычислитьЛогическое, ВычислитьСтроку, ВычислитьЧисло,
ВычислитьОбъект, Метаданные) вызывает клиент OpenFeature, напрямую они не нужны.
ОценитьПоСнимку(Ключ, Настройка, Контекст = Неопределено, ЗначениеПоУмолчанию = Неопределено) возвращает
Соответствие с полями значение, вариант, причина, кодОшибки.
Порядок разрешения значения:
- флаг выключен в окружении - значение по умолчанию, причина
DISABLED; - сработало правило таргетинга - вариант правила, причина
TARGETING_MATCH; - задана процентная выкатка - вариант либо значение по умолчанию, причина
SPLIT; - иначе вариант по умолчанию, причина
STATIC.
Процентная выкатка считается через bucketer: один и тот же пользователь всегда попадает в тот же бакет, поэтому при увеличении процента никто не выключается обратно.
Скрипт demo/ЖивойКлиент.os печатает поведение приложения и меняет его на глазах, когда флаг переключают в дашборде:
oscript demo/ЖивойКлиент.os http://localhost:3333 local-sdk-key dev 60
[19:38:35] user-1: старая корзина (disabled) | user-42: старая корзина (disabled)
[19:38:43] user-1: новая корзина (static) | user-42: новая корзина (static)
[19:38:49] user-1: новая корзина (split) | user-42: старая корзина (split)
- HTTPS не поддерживается: платформа не даёт TLS поверх
TCPСоединение. Для внешнего доступа нужен обратный прокси. - Поток изменений читается в фоновом задании; при обрыве переподключение выполняется с
Last-Event-ID, поэтому события не теряются.
opm run install
opm run test