Runtime Decide
3.1 Цель
Section titled “3.1 Цель”Decision API — это тот самый момент, когда продукт спрашивает: “какой вариант показать этому пользователю прямо сейчас?”. Платформа должна предоставлять продукту механизм получения актуальных значений флагов для конкретного пользователя/устройства в момент показа UI.
Смысл запроса со стороны продукта:
“Вот субъект (пользователь или устройство) и его атрибуты.
Дай значения для этих флагов так, как будто мы показываем интерфейс прямо сейчас”.
3.2 Входные данные
Section titled “3.2 Входные данные”В истории: при открытии экрана продукт передаёт информацию о пользователе, какой контекст (платформа, страна, версия, экран) — чтобы таргетинг и разрезы работали честно. При обращении продукт передаёт:
- идентификатор субъекта — стабильный идентификатор субъекта (например, идентификатор пользователя или устройства), по которому обеспечиваются:
- предсказуемая раздача трафика,
- «липкость» к варианту (stickiness) в рамках эксперимента.
- атрибуты субъекта — набор атрибутов (страна, версия приложения и т.п.), которые используются для таргетинга («правило участия»).
- список запрошенных флагов — список ключей флагов, значения которых нужны продукту для рендера.
3.3 Выходные данные
Section titled “3.3 Выходные данные”В истории: в ответ продукт получает «вот твой вариант + служебный «идентификатор решения»». Этот «идентификатор решения» потом связывает показ и события (клики/покупки) в одну цепочку. Для каждого запрошенного флага возвращается решение «что применить»:
- итоговое значение, которое продукт должен использовать;
- служебный идентификатор решения, чтобы связать показ и последующие события;
- если значение выдано экспериментом: идентификатор эксперимента и выбранный вариант.
3.4 Правила принятия решения
Section titled “3.4 Правила принятия решения”Здесь важно, чтобы правила были простыми и прозрачными: продакт должен понимать, почему пользователь попал в вариант B, а не в A. Для каждого «ключ флага» платформа должна определить итоговое значение так:
-
Если нет применимого активного эксперимента (эксперимент не запущен/на паузе или не применился) — вернуть значение по умолчанию флага.
-
Если есть активный эксперимент на этом флаге и он применим к субъекту:
- применить таргетинг
- выбрать вариант согласно весам вариантов
- вернуть значение выбранного варианта и метаданные эксперимента.
3.5 Требуемые свойства качества
Section titled “3.5 Требуемые свойства качества”В истории: это тот самый “не прыгать между вариантами”. Если пользователь вчера видел B, а сегодня внезапно увидел A — эксперимент превращается в шум.
3.5.1 Детерминизм
Section titled “3.5.1 Детерминизм”Одинаковый запрос при неизменной конфигурации (флаги/эксперименты/статусы/правила) должен возвращать одинаковый результат.
Цель: предсказуемость UI, корректная аналитика и воспроизводимость.
3.5.2 Stickiness
Section titled “3.5.2 Stickiness”Один и тот же «идентификатор субъекта» не должен “прыгать” между вариантами в рамках одного эксперимента, пока конфигурация эксперимента не меняется.
Цель: честное сравнение, пользовательский опыт без дерганий, чистая статистика.
3.5.3 Иные сбои
Section titled “3.5.3 Иные сбои”Сеть — штука капризная: запросы и события могут теряться или дублироваться. Поэтому идемпотентность и дедупликация — обязательны.
3.6 Защита пользователя от постоянного участия в экспериментах
Section titled “3.6 Защита пользователя от постоянного участия в экспериментах”В истории: пользователь не должен быть «вечным подопытным кроликом», который постоянно живёт в тестовых вариантах.
Платформа должна поддерживать политику участия пользователя в экспериментах:
- ограничение интенсивности участия (сколько активных экспериментов одновременно может влиять на одного субъекта);
- периоды «отдыха» (cooldown), когда после серии экспериментов пользователь чаще видит базовое поведение;
- прозрачные правила приоритезации, если на пользователя претендуют несколько экспериментов.
Важно: конкретный алгоритм квот/ротации не фиксируется в ТЗ, но решение участника должно объяснять, как выполняется эта пользовательская защита.
3.7 Технические проверки живости и готовности
Section titled “3.7 Технические проверки живости и готовности”Проблема, которую закрывает этот раздел: без разделения живости и готовности невозможно понять, сервис уже обслуживает запросы или только запущен как процесс.
/healthотвечает200, когда процесс приложения жив и может обрабатывать базовые служебные проверки./readyотвечает200, когда приложение готово принимать запросы.- Пока критичные зависимости не готовы,
/readyдолжен отвечать не-200. - После старта системы
/readyдолжен перейти в200не позднее чем за180секунд; если этого не произошло, жюри вправе запускать проверки в текущем состоянии системы. - Поведение
health/readinessдолжно быть отражено в инструкции запуска и в сценарии демонстрации.