1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
# frozen_string_literal: true
module Gitlab
class Experiment
module Rollout
autoload :Percent, 'gitlab/experiment/rollout/percent.rb'
autoload :Random, 'gitlab/experiment/rollout/random.rb'
autoload :RoundRobin, 'gitlab/experiment/rollout/round_robin.rb'
def self.resolve(klass, options = {})
options ||= {}
case klass
when String
Strategy.new(klass.classify.constantize, options)
when Symbol
Strategy.new("#{name}::#{klass.to_s.classify}".constantize, options)
when Class
Strategy.new(klass, options)
else
raise ArgumentError, "unable to resolve rollout from #{klass.inspect}"
end
end
class Base
attr_reader :experiment, :options
delegate :cache, :id, to: :experiment
def initialize(experiment, options = {})
raise ArgumentError, 'you must provide an experiment instance' unless experiment.class <= Gitlab::Experiment
@experiment = experiment
@options = options
end
def enabled?
true
end
def resolve
validate! # allow the rollout strategy to validate itself
assignment = execute_assignment
assignment == :control ? nil : assignment # avoid caching control by returning nil
end
private
def validate!
# base is always valid
end
def execute_assignment
behavior_names.first
end
def behavior_names
experiment.behaviors.keys
end
end
Strategy = Struct.new(:klass, :options) do
def for(experiment)
klass.new(experiment, options)
end
end
end
end
end
|