Add forced variant assignment for backend-only experiments (no request available)
Context
This is a follow-up to #579133 (closed) (requirement 3).
The first iteration (see gitlab-org/ruby/gems/gitlab-experiment MR) adds forced variant assignment via a glex_force query parameter. This covers:
✅ Requirement 1: Works in staging/production✅ Requirement 2: Handles anonymous (nil actor) entrypoint
However, the query parameter approach requires a request object with params to be available. This does not cover cases where:
- The variant is decided fully in the backend with no clear UI/request entrypoint
- The experiment runs in a background job (Sidekiq), service object, webhook handler, or cron job
- Passing a parameter from a request down to where the experiment runs is complicated or impossible (deeply nested service calls)
Requirements
- Must work without a
requestobject available in the experiment context - Must be able to target a specific user/actor for a specific experiment
- Should integrate with the existing GLEX cache so the forced variant persists and behaves like a normal assignment
- Should be clearable (allow returning to normal rollout assignment)
Ideas
- Redis-backed override keyed by context key or user identity: A dedicated endpoint (or ChatOps command) stores the override in Redis.
forced_variant_namechecks this store when no request param is available. Adds a Redis read per experiment resolution (can be request-level cached). - ChatOps integration:
/experiment force signup_cta candidate user:123writes the override to Redis. Clean UX for internal teams. - Actor name convention: Prefix/suffix the actor identifier (e.g.,
bob_glex_candidate) to signal forced assignment. Fragile but no infrastructure needed. - Configuration-level override map:
Configuration.forced_assignments = { 'experiment_name' => { user_id => :variant } }. Simple but doesn't scale.
Relates to
- #579133 (closed) (parent issue)
- gitlab-org/ruby/gems/gitlab-experiment (GLEX gem)
Edited by 🤖 GitLab Bot 🤖