Class: Gitlab::Experiment
- Inherits:
-
Object
- Object
- Gitlab::Experiment
show all
- Includes:
- BaseInterface, Cache, Callbacks
- Defined in:
- lib/gitlab/experiment.rb,
lib/gitlab/experiment/dsl.rb,
lib/gitlab/experiment/cache.rb,
lib/gitlab/experiment/rspec.rb,
lib/gitlab/experiment/engine.rb,
lib/gitlab/experiment/context.rb,
lib/gitlab/experiment/cookies.rb,
lib/gitlab/experiment/rollout.rb,
lib/gitlab/experiment/variant.rb,
lib/gitlab/experiment/version.rb,
lib/gitlab/experiment/callbacks.rb,
lib/gitlab/experiment/configuration.rb,
lib/gitlab/experiment/base_interface.rb,
lib/gitlab/experiment/rollout/random.rb,
lib/gitlab/experiment/rollout/round_robin.rb,
lib/gitlab/experiment/cache/redis_hash_store.rb
Defined Under Namespace
Modules: BaseInterface, Cache, Callbacks, Cookies, Dsl, RSpecHelpers, RSpecMatchers, Rollout
Classes: Configuration, Context, Engine, Variant
Constant Summary
collapse
- VERSION =
'0.5.4'
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Cache
#cache, #cache_key, #cache_variant
#behaviors, #flipper_id, #id, #initialize, #inspect, #variant_names
Class Method Details
.default_rollout(rollout = nil, options = {}) ⇒ Object
31
32
33
34
35
|
# File 'lib/gitlab/experiment.rb', line 31
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) ⇒ Object
37
38
39
40
41
|
# File 'lib/gitlab/experiment.rb', line 37
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
|
.published_experiments ⇒ Object
49
50
51
|
# File 'lib/gitlab/experiment.rb', line 49
def published_experiments
RequestStore.store[:published_gitlab_experiments] || {}
end
|
.segment(*filter_list, variant:, **options, &block) ⇒ Object
43
44
45
46
47
|
# File 'lib/gitlab/experiment.rb', line 43
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
|
Instance Method Details
#candidate(name = nil, &block) ⇒ Object
Also known as:
try
63
64
65
66
|
# File 'lib/gitlab/experiment.rb', line 63
def candidate(name = nil, &block)
name = (name || :candidate).to_s
behaviors[name] = block
end
|
#context(value = nil) ⇒ Object
69
70
71
72
73
74
|
# File 'lib/gitlab/experiment.rb', line 69
def context(value = nil)
return @context if value.blank?
@context.value(value)
@context
end
|
#control(&block) ⇒ Object
Also known as:
use
58
59
60
|
# File 'lib/gitlab/experiment.rb', line 58
def control(&block)
candidate(:control, &block)
end
|
#enabled? ⇒ Boolean
119
120
121
|
# File 'lib/gitlab/experiment.rb', line 119
def enabled?
true
end
|
#exclude! ⇒ Object
99
100
101
|
# File 'lib/gitlab/experiment.rb', line 99
def exclude!
@excluded = true
end
|
#excluded? ⇒ Boolean
123
124
125
126
127
|
# File 'lib/gitlab/experiment.rb', line 123
def excluded?
return @excluded if defined?(@excluded)
@excluded = !run_callbacks(:exclusion_check) { :not_excluded }
end
|
#experiment_group? ⇒ Boolean
#key_for(source, seed = name) ⇒ Object
#publish(result) ⇒ Object
107
108
109
110
111
|
# File 'lib/gitlab/experiment.rb', line 107
def publish(result)
instance_exec(result, &Configuration.publishing_behavior)
(RequestStore.store[:published_gitlab_experiments] ||= {})[name] = signature.merge(excluded: excluded?)
end
|
#rollout(rollout = nil, options = {}) ⇒ Object
93
94
95
96
97
|
# File 'lib/gitlab/experiment.rb', line 93
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) ⇒ Object
103
104
105
|
# File 'lib/gitlab/experiment.rb', line 103
def run(variant_name = nil)
@result ||= super(variant(variant_name).name)
end
|
#should_track? ⇒ Boolean
133
134
135
|
# File 'lib/gitlab/experiment.rb', line 133
def should_track?
enabled? && @context.trackable? && !excluded?
end
|
#signature ⇒ Object
137
138
139
|
# File 'lib/gitlab/experiment.rb', line 137
def signature
{ variant: variant.name, experiment: name }.merge(context.signature)
end
|
#track(action, **event_args) ⇒ Object
113
114
115
116
117
|
# File 'lib/gitlab/experiment.rb', line 113
def track(action, **event_args)
return unless should_track?
instance_exec(action, event_args, &Configuration.tracking_behavior)
end
|
#variant(value = nil) ⇒ Object
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/gitlab/experiment.rb', line 76
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
|