42 lines
2.4 KiB
Markdown
42 lines
2.4 KiB
Markdown
# 3. Драйверы и NFR
|
||
|
||
## Корректность и воспроизводимость
|
||
|
||
- Детерминированная раздача варианта через SHA-256 hash по `subject_id` и `experiment_id`.
|
||
- Один активный эксперимент на флаг (`running/paused`) через DB constraint.
|
||
- Строгие переходы lifecycle и блокировка недопустимых переходов.
|
||
- Идемпотентность событий по `event_id`.
|
||
|
||
## Safety
|
||
|
||
- Guardrails с порогом, окном наблюдения и автоматическим действием (`pause` или `rollback`).
|
||
- Ограничение участия пользователя: max concurrent + cooldown.
|
||
- Conflict domains для детерминированного разрешения коллизий экспериментов.
|
||
|
||
## Целостность аналитики
|
||
|
||
- Атрибуция через `decision_id`.
|
||
- Для событий с `requires_exposure=True`: без exposure событие уходит в `PendingEvent` и промотируется позже.
|
||
- Отчёт строится по вариантам и выбранным метрикам эксперимента.
|
||
|
||
## Эксплуатация
|
||
|
||
- Health/readiness probes.
|
||
- Prometheus-инструментация HTTP и бизнес-счётчиков.
|
||
- Structured logging с correlation id.
|
||
- Регламентные фоновые задачи Celery.
|
||
|
||
## Производительность
|
||
|
||
Реализовано:
|
||
- кэш флагов и активных экспериментов;
|
||
- кэш результата `decide` (TTL через `DECISION_RESULT_CACHE_TTL_SECONDS`);
|
||
- режим записи `Decision`: `sync|async|disabled` (`DECISION_WRITE_MODE`) с принудительным sync для `experiment_assigned`;
|
||
- async persistence через `events.persist_decision`;
|
||
- `reports` считает `average` через `Avg`, `percentile` через DB aggregate (`PERCENTILE_CONT` для PostgreSQL);
|
||
- в `reports` убрана materialization `decision_ids`, используется `Subquery`.
|
||
|
||
Текущие ограничения:
|
||
- в режиме `async` устойчивость записи зависит от здоровья Celery worker/broker;
|
||
- SQL-ветка percentile зависит от СУБД (PostgreSQL/не-PostgreSQL fallback);
|