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/rollout/first.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.2'
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) ⇒ Object
30
31
32
33
34
|
# File 'lib/gitlab/experiment.rb', line 30
def default_rollout(rollout = nil)
return @rollout ||= Configuration.default_rollout if rollout.blank?
@rollout = Rollout.resolve(rollout)
end
|
.exclude(*filter_list, **options, &block) ⇒ Object
36
37
38
39
40
|
# File 'lib/gitlab/experiment.rb', line 36
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
|
.segment(*filter_list, variant:, **options, &block) ⇒ Object
42
43
44
45
46
|
# File 'lib/gitlab/experiment.rb', line 42
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
58
59
60
61
|
# File 'lib/gitlab/experiment.rb', line 58
def candidate(name = nil, &block)
name = (name || :candidate).to_s
behaviors[name] = block
end
|
#context(value = nil) ⇒ Object
64
65
66
67
68
69
|
# File 'lib/gitlab/experiment.rb', line 64
def context(value = nil)
return @context if value.blank?
@context.value(value)
@context
end
|
#control(&block) ⇒ Object
Also known as:
use
53
54
55
|
# File 'lib/gitlab/experiment.rb', line 53
def control(&block)
candidate(:control, &block)
end
|
#enabled? ⇒ Boolean
114
115
116
|
# File 'lib/gitlab/experiment.rb', line 114
def enabled?
true
end
|
#exclude! ⇒ Object
96
97
98
|
# File 'lib/gitlab/experiment.rb', line 96
def exclude!
@excluded = true
end
|
#excluded? ⇒ Boolean
118
119
120
121
122
|
# File 'lib/gitlab/experiment.rb', line 118
def excluded?
return @excluded if defined?(@excluded)
@excluded = !run_callbacks(:exclusion_check) { :not_excluded }
end
|
#experiment_group? ⇒ Boolean
124
125
126
|
# File 'lib/gitlab/experiment.rb', line 124
def experiment_group?
instance_exec(@variant_name, &Configuration.inclusion_resolver)
end
|
#key_for(hash) ⇒ Object
136
137
138
|
# File 'lib/gitlab/experiment.rb', line 136
def key_for(hash)
instance_exec(hash, &Configuration.context_hash_strategy)
end
|
#name ⇒ Object
49
50
51
|
# File 'lib/gitlab/experiment.rb', line 49
def name
[Configuration.name_prefix, @name].compact.join('_')
end
|
#publish(result) ⇒ Object
104
105
106
|
# File 'lib/gitlab/experiment.rb', line 104
def publish(result)
instance_exec(result, &Configuration.publishing_behavior)
end
|
#rollout(rollout = nil) ⇒ Object
90
91
92
93
94
|
# File 'lib/gitlab/experiment.rb', line 90
def rollout(rollout = nil)
return @rollout ||= self.class.default_rollout if rollout.blank?
@rollout = Rollout.resolve(rollout)
end
|
#run(variant_name = nil) ⇒ Object
100
101
102
|
# File 'lib/gitlab/experiment.rb', line 100
def run(variant_name = nil)
@result ||= super(variant(variant_name).name)
end
|
#should_track? ⇒ Boolean
128
129
130
|
# File 'lib/gitlab/experiment.rb', line 128
def should_track?
enabled? && @context.trackable? && !excluded?
end
|
#signature ⇒ Object
132
133
134
|
# File 'lib/gitlab/experiment.rb', line 132
def signature
{ variant: variant.name, experiment: name }.merge(context.signature)
end
|
#track(action, **event_args) ⇒ Object
108
109
110
111
112
|
# File 'lib/gitlab/experiment.rb', line 108
def track(action, **event_args)
return unless should_track?
instance_exec(action, event_args, &Configuration.tracking_behavior)
end
|
#variant(value = nil) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/gitlab/experiment.rb', line 71
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 ||= :control if excluded?
result = cache_variant(@variant_name) { resolve_variant_name }
@variant_name = result.to_sym if result.present?
end
run_callbacks(segmentation_callback_chain) do
@variant_name ||= :control
Variant.new(name: @variant_name.to_s)
end
ensure
@resolving_variant = false
end
|