class Gitlab::Experiment
Constants
- Error
- InvalidRolloutRules
- VERSION
- Variant
Public Class Methods
default_rollout(rollout = nil, options = {})
click to toggle source
# File lib/gitlab/experiment.rb, line 33 def default_rollout(rollout = nil, options = {}) return @rollout ||= Configuration.default_rollout if rollout.blank? @rollout = Rollout.resolve(rollout).new(options) end
exclude(*filter_list, **options, &block)
click to toggle source
# File lib/gitlab/experiment.rb, line 39 def exclude(*filter_list, **options, &block) build_callback(:exclusion_check, filter_list.unshift(block), **options) do |target, callback| throw(:abort) if target.instance_variable_get(:@excluded) || callback.call(target, nil) == true end end
model_name()
click to toggle source
used for generating routes
# File lib/gitlab/experiment/engine.rb, line 10 def self.model_name ActiveModel::Name.new(self, Gitlab) end
published_experiments()
click to toggle source
# File lib/gitlab/experiment.rb, line 51 def published_experiments RequestStore.store[:published_gitlab_experiments] || {} end
segment(*filter_list, variant:, **options, &block)
click to toggle source
# File lib/gitlab/experiment.rb, line 45 def segment(*filter_list, variant:, **options, &block) build_callback(:segmentation_check, filter_list.unshift(block), **options) do |target, callback| target.variant(variant) if target.instance_variable_get(:@variant_name).nil? && callback.call(target, nil) end end
Public Instance Methods
candidate(name = nil, &block)
click to toggle source
# File lib/gitlab/experiment.rb, line 65 def candidate(name = nil, &block) name = (name || :candidate).to_s behaviors[name] = block end
Also aliased as: try
context(value = nil)
click to toggle source
# File lib/gitlab/experiment.rb, line 71 def context(value = nil) return @context if value.blank? @context.value(value) @context end
control(&block)
click to toggle source
# File lib/gitlab/experiment.rb, line 60 def control(&block) candidate(:control, &block) end
Also aliased as: use
enabled?()
click to toggle source
# File lib/gitlab/experiment.rb, line 130 def enabled? true end
exclude!()
click to toggle source
# File lib/gitlab/experiment.rb, line 101 def exclude! @excluded = true end
excluded?()
click to toggle source
# File lib/gitlab/experiment.rb, line 134 def excluded? return @excluded if defined?(@excluded) @excluded = !run_callbacks(:exclusion_check) { :not_excluded } end
experiment_group?()
click to toggle source
# File lib/gitlab/experiment.rb, line 140 def experiment_group? instance_exec(@variant_name, &Configuration.inclusion_resolver) end
key_for(source, seed = name)
click to toggle source
# File lib/gitlab/experiment.rb, line 152 def key_for(source, seed = name) # TODO: Added deprecation in release 0.6.0 if (block = Configuration.instance_variable_get(:@__context_hash_strategy)) return instance_exec(source, seed, &block) end source = source.keys + source.values if source.is_a?(Hash) ingredients = Array(source).map { |v| identify(v) } ingredients.unshift(seed).unshift(Configuration.context_key_secret) Digest::SHA2.new(Configuration.context_key_bit_length).hexdigest(ingredients.join('|')) end
name()
click to toggle source
# File lib/gitlab/experiment.rb, line 56 def name [Configuration.name_prefix, @name].compact.join('_') end
process_redirect_url(url)
click to toggle source
# File lib/gitlab/experiment.rb, line 123 def process_redirect_url(url) return unless Configuration.redirect_url_validator&.call(url) track('visited', url: url) url # return the url, which allows for mutation end
publish(result)
click to toggle source
# File lib/gitlab/experiment.rb, line 111 def publish(result) instance_exec(result, &Configuration.publishing_behavior) (RequestStore.store[:published_gitlab_experiments] ||= {})[name] = signature.merge(excluded: excluded?) end
rollout(rollout = nil, options = {})
click to toggle source
# File lib/gitlab/experiment.rb, line 95 def rollout(rollout = nil, options = {}) return @rollout ||= self.class.default_rollout(nil, options) if rollout.blank? @rollout = Rollout.resolve(rollout).new(options) end
run(variant_name = nil)
click to toggle source
Calls superclass method
# File lib/gitlab/experiment.rb, line 105 def run(variant_name = nil) @result ||= super(variant(variant_name).name) rescue Scientist::BehaviorMissing => e raise Error, e end
should_track?()
click to toggle source
# File lib/gitlab/experiment.rb, line 144 def should_track? enabled? && @context.trackable? && !excluded? end
signature()
click to toggle source
# File lib/gitlab/experiment.rb, line 148 def signature { variant: variant.name, experiment: name }.merge(context.signature) end
track(action, **event_args)
click to toggle source
# File lib/gitlab/experiment.rb, line 117 def track(action, **event_args) return unless should_track? instance_exec(action, event_args, &Configuration.tracking_behavior) end
variant(value = nil)
click to toggle source
# File lib/gitlab/experiment.rb, line 78 def variant(value = nil) @variant_name = cache_variant(value) if value.present? return Variant.new(name: (@variant_name || :unresolved).to_s) if @variant_name || @resolving_variant if enabled? @resolving_variant = true @variant_name = cached_variant_resolver(@variant_name) end run_callbacks(segmentation_callback_chain) do @variant_name ||= :control Variant.new(name: @variant_name.to_s) end ensure @resolving_variant = false end
Protected Instance Methods
identify(object)
click to toggle source
# File lib/gitlab/experiment.rb, line 168 def identify(object) (object.respond_to?(:to_global_id) ? object.to_global_id : object).to_s end
resolve_variant_name()
click to toggle source
# File lib/gitlab/experiment.rb, line 178 def resolve_variant_name rollout.rollout_for(self) if experiment_group? end
segmentation_callback_chain()
click to toggle source
# File lib/gitlab/experiment.rb, line 172 def segmentation_callback_chain return :segmentation_check if @variant_name.nil? && enabled? && !excluded? :unsegmented end