trailguide 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +191 -293
- data/app/views/trail_guide/admin/experiments/_btn_join.html.erb +1 -1
- data/app/views/trail_guide/admin/experiments/_header.html.erb +3 -3
- data/config/initializers/admin.rb +19 -0
- data/config/initializers/experiment.rb +261 -0
- data/config/initializers/trailguide.rb +6 -279
- data/lib/trail_guide/adapters.rb +2 -0
- data/lib/trail_guide/adapters/experiments.rb +8 -0
- data/lib/trail_guide/adapters/experiments/redis.rb +48 -0
- data/lib/trail_guide/adapters/participants/cookie.rb +1 -0
- data/lib/trail_guide/adapters/participants/unity.rb +9 -1
- data/lib/trail_guide/adapters/variants.rb +8 -0
- data/lib/trail_guide/adapters/variants/redis.rb +52 -0
- data/lib/trail_guide/admin/engine.rb +1 -0
- data/lib/trail_guide/algorithms.rb +4 -0
- data/lib/trail_guide/algorithms/algorithm.rb +29 -0
- data/lib/trail_guide/algorithms/bandit.rb +9 -18
- data/lib/trail_guide/algorithms/distributed.rb +8 -15
- data/lib/trail_guide/algorithms/random.rb +2 -12
- data/lib/trail_guide/algorithms/static.rb +34 -0
- data/lib/trail_guide/algorithms/weighted.rb +5 -17
- data/lib/trail_guide/catalog.rb +79 -35
- data/lib/trail_guide/config.rb +2 -4
- data/lib/trail_guide/engine.rb +2 -1
- data/lib/trail_guide/experiments/base.rb +41 -24
- data/lib/trail_guide/experiments/combined_config.rb +4 -0
- data/lib/trail_guide/experiments/config.rb +59 -30
- data/lib/trail_guide/experiments/participant.rb +4 -2
- data/lib/trail_guide/helper.rb +4 -216
- data/lib/trail_guide/helper/experiment_proxy.rb +160 -0
- data/lib/trail_guide/helper/helper_proxy.rb +62 -0
- data/lib/trail_guide/metrics/config.rb +2 -0
- data/lib/trail_guide/metrics/goal.rb +17 -15
- data/lib/trail_guide/participant.rb +10 -2
- data/lib/trail_guide/unity.rb +17 -8
- data/lib/trail_guide/variant.rb +15 -11
- data/lib/trail_guide/version.rb +2 -2
- metadata +13 -3
@@ -3,7 +3,7 @@
|
|
3
3
|
<%= link_to trail_guide_admin.leave_experiment_path(experiment.experiment_name), class: "btn btn-sm btn-outline-secondary", method: :put, data: {toggle: :tooltip}, title: 'leave this cohort' do %>
|
4
4
|
<span class="fas fa-sign-out-alt fa-flip-horizontal" />
|
5
5
|
<% end %>
|
6
|
-
<% elsif !experiment.calibrating? && !experiment.winner? && experiment.configuration.
|
6
|
+
<% elsif !experiment.calibrating? && !experiment.winner? && experiment.configuration.sticky_assignment? && (!experiment.is_combined? || (!participant.participating?(experiment.parent) || participant.variant(experiment.parent).name == variant.name)) %>
|
7
7
|
<%= link_to trail_guide_admin.join_experiment_path(experiment.experiment_name, variant.name), class: "btn btn-sm btn-secondary", method: :put, data: {toggle: :tooltip}, title: 'join this cohort' do %>
|
8
8
|
<span class="fas fa-sign-in-alt" />
|
9
9
|
<% end %>
|
@@ -31,9 +31,9 @@
|
|
31
31
|
<% if experiment.groups.count > 0 %>
|
32
32
|
<p class="text-muted" style="padding: 0; margin: 0;">
|
33
33
|
<span class="fas fa-th-large" data-toggle="tooltip" title="experiment groups"></span>
|
34
|
-
|
35
|
-
|
36
|
-
<% end %>
|
34
|
+
<%= raw(experiment.groups.map do |group| %>
|
35
|
+
<% link_to group.to_s.humanize.titleize, trail_guide_admin.group_path(group), class: "text-muted" %>
|
36
|
+
<% end.join(', ')) %>
|
37
37
|
</p>
|
38
38
|
<% end %>
|
39
39
|
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# admin ui configuration
|
2
|
+
#
|
3
|
+
TrailGuide::Admin.configure do |config|
|
4
|
+
# display title for admin UI
|
5
|
+
#
|
6
|
+
config.title = 'TrailGuide'
|
7
|
+
|
8
|
+
# display subtitle for admin UI
|
9
|
+
#
|
10
|
+
config.subtitle = 'Experiments and A/B Tests'
|
11
|
+
|
12
|
+
# request parameter can be used to "peek" at results even before an
|
13
|
+
# experiment's target_sample_size has been hit if one is configured
|
14
|
+
#
|
15
|
+
# if you set this to nil, admins will not be able to peek at experiment
|
16
|
+
# results until the target sample size is hit or the experiment is stopped
|
17
|
+
#
|
18
|
+
config.peek_parameter = nil
|
19
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# base experiment configuration
|
2
|
+
#
|
3
|
+
TrailGuide::Experiment.configure do |config|
|
4
|
+
# the default algorithm to use for new experiments
|
5
|
+
config.algorithm = :distributed
|
6
|
+
|
7
|
+
# whether or not experiments must be started manually
|
8
|
+
#
|
9
|
+
# true experiments must be started manually via the admin UI or console
|
10
|
+
# false experiments will start the first time they're encountered by a user
|
11
|
+
config.start_manually = true
|
12
|
+
|
13
|
+
# whether or not participants will be reset upon conversion
|
14
|
+
#
|
15
|
+
# true participants will only be entered into the experiment once, and the
|
16
|
+
# variant group they belong to is sticky for the duration
|
17
|
+
# false participants will be reset upon conversion and be able to re-enter
|
18
|
+
# the experiment if they encounter it again
|
19
|
+
config.reset_manually = true
|
20
|
+
|
21
|
+
# whether or not individual assignment is sticky when returning a variant
|
22
|
+
#
|
23
|
+
# this can be useful if you are using a custom, content-based algorithm where
|
24
|
+
# the variant is determined by content rather than user bucketing, and you
|
25
|
+
# want to treat participation more like impressions (i.e. for seo experiments)
|
26
|
+
#
|
27
|
+
# when this option is set to false, conversions will always be tracked against
|
28
|
+
# the last variant that the participant was served
|
29
|
+
#
|
30
|
+
# true participation is incremented the first time a participant is
|
31
|
+
# enrolled, and the participant is assigned their selection for future
|
32
|
+
# reference, stored via the configured participant adapter
|
33
|
+
# false participation will be incremented every time a variant is selected,
|
34
|
+
# and the participant will not be forced into a bucket
|
35
|
+
config.sticky_assignment = true
|
36
|
+
|
37
|
+
# whether or not to enter participants into a variant when using the override
|
38
|
+
# parameter to preview variants
|
39
|
+
#
|
40
|
+
# true using overrides to preview experiments will enter participants into
|
41
|
+
# that variant group
|
42
|
+
# false using overrides to preview experiments will not enter participants
|
43
|
+
# into the experment (won't persist their variant group)
|
44
|
+
config.store_override = false
|
45
|
+
|
46
|
+
# whether or not we track participants when using the override parameter to
|
47
|
+
# preview variants
|
48
|
+
#
|
49
|
+
# true using overrides to preview experiments will increment the
|
50
|
+
# participant count for the override variant
|
51
|
+
# false using overrides to preview experiments will not increment the
|
52
|
+
# participant count for the override variant
|
53
|
+
config.track_override = false
|
54
|
+
|
55
|
+
# whether or not to continue tracking conversions after a winner has been
|
56
|
+
# selected in order to continue monitoring performance of the variant
|
57
|
+
#
|
58
|
+
# true continues to track conversions after a winner has been selected (as
|
59
|
+
# long as the experiment is still running)
|
60
|
+
# false all conversion and participation tracking stops once a winner has
|
61
|
+
# been selected
|
62
|
+
config.track_winner_conversions = false
|
63
|
+
|
64
|
+
# whether or not to allow multiple conversions of the same goal, or default
|
65
|
+
# conversion if no goals are defined
|
66
|
+
#
|
67
|
+
# true tracks multiple participant conversions for the same goal as long
|
68
|
+
# as they haven't been reset (see config.reset_manually)
|
69
|
+
# false prevents tracking multiple conversions for a single participant
|
70
|
+
config.allow_multiple_conversions = false
|
71
|
+
|
72
|
+
# whether or not to allow participants to convert for multiple defined goals
|
73
|
+
#
|
74
|
+
# true allows participants to convert more than one goal as long as they
|
75
|
+
# haven't been reset (see config.reset_manually)
|
76
|
+
# false prevents converting to multiple goals for a single participant
|
77
|
+
config.allow_multiple_goals = false
|
78
|
+
|
79
|
+
# whether or not to enable calibration before an experiment is started - the
|
80
|
+
# participants and conversions will be tracked for your control group while
|
81
|
+
# an experiment remains unstarted, which can be useful for gathering a
|
82
|
+
# baseline conversion rate if you don't already have one
|
83
|
+
#
|
84
|
+
# control is always returned for unstarted experiments by default, and this
|
85
|
+
# configuration only affects whether or not to track metrics
|
86
|
+
#
|
87
|
+
# this setting only applies when start_manually is also true
|
88
|
+
#
|
89
|
+
# true metrics for participation and conversion will be tracked for the
|
90
|
+
# control group until the experiment is started
|
91
|
+
# false metrics will not be tracked while the experiment remains unstarted
|
92
|
+
config.enable_calibration = false
|
93
|
+
|
94
|
+
# whether or not to skip the request filtering for this experiment - can be
|
95
|
+
# useful when defining content-based experiments with custom algorithms which
|
96
|
+
# bucket participants strictly based on additional content metadata and you
|
97
|
+
# want to expose those variants to crawlers and bots
|
98
|
+
#
|
99
|
+
# true requests that would otherwise be filtered based on your
|
100
|
+
# TrailGuide.configuration.request_filter config will instead be
|
101
|
+
# allowed through to this experiment
|
102
|
+
# false default behavior, requests will be filtered based on your config
|
103
|
+
config.skip_request_filter = false
|
104
|
+
|
105
|
+
# whether or not this experiment can be resumed after it's stopped - allows
|
106
|
+
# temporarily "pausing" an experiment then resuming it without losing metrics
|
107
|
+
#
|
108
|
+
# true this experiment can be paused and resumed
|
109
|
+
# false this experiment can only be stopped and reset/restarted
|
110
|
+
config.can_resume = false
|
111
|
+
|
112
|
+
# set a default target sample size for all experiments - this will prevent
|
113
|
+
# metrics and stats from being displayed in the admin UI until the sample size
|
114
|
+
# is reached or the experiment is stopped
|
115
|
+
#
|
116
|
+
# config.target_sample_size = nil
|
117
|
+
|
118
|
+
# callback when connecting to redis fails and trailguide falls back to always
|
119
|
+
# returning control variants
|
120
|
+
config.on_redis_failover = -> (experiment, error) do
|
121
|
+
TrailGuide.logger.error error
|
122
|
+
end
|
123
|
+
|
124
|
+
# callback on experiment start, either manually via UI/console or
|
125
|
+
# automatically depending on config.start_manually, can be used for logging,
|
126
|
+
# tracking, etc.
|
127
|
+
#
|
128
|
+
# context may or may not be present depending on how you're triggering the
|
129
|
+
# action - if you're using the admin, this will be the admin controller
|
130
|
+
# context, if you're in a console you have the option to pass a context to
|
131
|
+
# `experiment.start!` or not
|
132
|
+
#
|
133
|
+
# config.on_start = -> (experiment, context) { ... }
|
134
|
+
|
135
|
+
# callback on experiment schedule manually via UI/console, can be used for logging,
|
136
|
+
# tracking, etc.
|
137
|
+
#
|
138
|
+
# experiments can only be scheduled if config.start_manually is true
|
139
|
+
#
|
140
|
+
# context may or may not be present depending on how you're triggering the
|
141
|
+
# action - if you're using the admin, this will be the admin controller
|
142
|
+
# context, if you're in a console you have the option to pass a context to
|
143
|
+
# `experiment.schedule!` or not
|
144
|
+
#
|
145
|
+
# config.on_schedule = -> (experiment, start_at, stop_at, context) { ... }
|
146
|
+
|
147
|
+
# callback on experiment stop manually via UI/console, can be used for
|
148
|
+
# logging, tracking, etc.
|
149
|
+
#
|
150
|
+
# context may or may not be present depending on how you're triggering the
|
151
|
+
# action - if you're using the admin, this will be the admin controller
|
152
|
+
# context, if you're in a console you have the option to pass a context to
|
153
|
+
# `experiment.stop!` or not
|
154
|
+
#
|
155
|
+
# config.on_stop = -> (experiment, context) { ... }
|
156
|
+
|
157
|
+
# callback on experiment pause manually via UI/console, can be used for
|
158
|
+
# logging, tracking, etc.
|
159
|
+
#
|
160
|
+
# context may or may not be present depending on how you're triggering the
|
161
|
+
# action - if you're using the admin, this will be the admin controller
|
162
|
+
# context, if you're in a console you have the option to pass a context to
|
163
|
+
# `experiment.pause!` or not
|
164
|
+
#
|
165
|
+
# config.on_pause = -> (experiment, context) { ... }
|
166
|
+
|
167
|
+
# callback on experiment resume manually via UI/console, can be used for
|
168
|
+
# logging, tracking, etc.
|
169
|
+
#
|
170
|
+
# context may or may not be present depending on how you're triggering the
|
171
|
+
# action - if you're using the admin, this will be the admin controller
|
172
|
+
# context, if you're in a console you have the option to pass a context to
|
173
|
+
# `experiment.resume!` or not
|
174
|
+
#
|
175
|
+
# config.on_resume = -> (experiment, context) { ... }
|
176
|
+
|
177
|
+
# callback on experiment delete manually via UI/console, can be used for
|
178
|
+
# logging, tracking, etc. - will also be triggered by a reset
|
179
|
+
#
|
180
|
+
# context may or may not be present depending on how you're triggering the
|
181
|
+
# action - if you're using the admin, this will be the admin controller
|
182
|
+
# context, if you're in a console you have the option to pass a context to
|
183
|
+
# `experiment.delete!` or not
|
184
|
+
#
|
185
|
+
# config.on_delete = -> (experiment, context) { ... }
|
186
|
+
|
187
|
+
# callback on experiment reset manually via UI/console, can be used for
|
188
|
+
# logging, tracking, etc. - will also trigger any on_delete callbacks
|
189
|
+
#
|
190
|
+
# context may or may not be present depending on how you're triggering the
|
191
|
+
# action - if you're using the admin, this will be the admin controller
|
192
|
+
# context, if you're in a console you have the option to pass a context to
|
193
|
+
# `experiment.reset!` or not
|
194
|
+
#
|
195
|
+
# config.on_reset = -> (experiment, context) { ... }
|
196
|
+
|
197
|
+
# callback when a winner is selected manually via UI/console, can be used for
|
198
|
+
# logging, tracking, etc.
|
199
|
+
#
|
200
|
+
# context may or may not be present depending on how you're triggering the
|
201
|
+
# action - if you're using the admin, this will be the admin controller
|
202
|
+
# context, if you're in a console you have the option to pass a context to
|
203
|
+
# `experiment.declare_winner!` or not
|
204
|
+
#
|
205
|
+
# config.on_winner = -> (experiment, winner, context) { ... }
|
206
|
+
|
207
|
+
|
208
|
+
# callback when a participant is entered into a variant for the first time,
|
209
|
+
# can be used for logging, tracking, etc.
|
210
|
+
#
|
211
|
+
# config.on_choose = -> (experiment, variant, participant, metadata) { ... }
|
212
|
+
|
213
|
+
# callback every time a participant is returned a variant in the experiment,
|
214
|
+
# can be used for logging, tracking, etc.
|
215
|
+
#
|
216
|
+
# config.on_use = -> (experiment, variant, participant, metadata) { ... }
|
217
|
+
|
218
|
+
# callback when a participant converts for a variant in the experiment, can be
|
219
|
+
# used for logging, tracking, etc.
|
220
|
+
#
|
221
|
+
# config.on_convert = -> (experiment, checkpoint, variant, participant, metadata) { ... }
|
222
|
+
|
223
|
+
|
224
|
+
# callback that can short-circuit participation based on your own logic, which
|
225
|
+
# gets called *after* all the core engine checks (i.e. that the user is
|
226
|
+
# not excluded or already participating, etc.)
|
227
|
+
#
|
228
|
+
# `allowed` will be the value returned by any previous callbacks in the chain
|
229
|
+
#
|
230
|
+
# should return true or false
|
231
|
+
#
|
232
|
+
# config.allow_participation = -> (experiment, allowed, participant, metadata) { ... return true }
|
233
|
+
|
234
|
+
|
235
|
+
# callback that can short-circuit conversion based on your own logic, which
|
236
|
+
# gets called *after* all the core engine checks (i.e. that the user is
|
237
|
+
# participating in the experiment, is within the bounds of the experiment
|
238
|
+
# configuration for allow_multiple_*, etc.)
|
239
|
+
#
|
240
|
+
# `allowed` will be the value returned by any previous callbacks in the chain
|
241
|
+
#
|
242
|
+
# should return true or false
|
243
|
+
#
|
244
|
+
# config.allow_conversion = -> (experiment, allowed, checkpoint, variant, participant, metadata) { ... return true }
|
245
|
+
|
246
|
+
|
247
|
+
# callback that can be used to modify the rollout of a selected winner - for
|
248
|
+
# example you could use a custom algorithm or even something like the flipper
|
249
|
+
# gem to do a "feature rollout" from your control variant to your winner for
|
250
|
+
# all users
|
251
|
+
#
|
252
|
+
# be aware that when using this alongside track_winner_conversions, whatever
|
253
|
+
# variant is returned from this callback chain is what will be tracked for
|
254
|
+
# participation and conversion as long as the experiment is still running
|
255
|
+
#
|
256
|
+
# `winner` will be the variant returned by any previous callbacks in the chain
|
257
|
+
#
|
258
|
+
# must return an experiment variant
|
259
|
+
#
|
260
|
+
# config.rollout_winner = -> (experiment, winner, participant) { return winner }
|
261
|
+
end
|
@@ -4,6 +4,12 @@ TrailGuide.configure do |config|
|
|
4
4
|
# logger object
|
5
5
|
config.logger = Rails.logger
|
6
6
|
|
7
|
+
# paths where trailguide will look for experiment configs and classes, each
|
8
|
+
# can be configured with multiple paths
|
9
|
+
config.paths.configs << 'config/experiments.*'
|
10
|
+
config.paths.configs << 'config/experiments/**/*'
|
11
|
+
config.paths.classes << 'app/experiments/**/*.rb'
|
12
|
+
|
7
13
|
# url string or initialized Redis object
|
8
14
|
config.redis = ENV['REDIS_URL']
|
9
15
|
|
@@ -117,282 +123,3 @@ TrailGuide.configure do |config|
|
|
117
123
|
is_filtered_ip_address?
|
118
124
|
end
|
119
125
|
end
|
120
|
-
|
121
|
-
# base experiment configuration
|
122
|
-
#
|
123
|
-
TrailGuide::Experiment.configure do |config|
|
124
|
-
# the default algorithm to use for new experiments
|
125
|
-
config.algorithm = :weighted
|
126
|
-
|
127
|
-
# whether or not experiments must be started manually
|
128
|
-
#
|
129
|
-
# true experiments must be started manually via the admin UI or console
|
130
|
-
# false experiments will start the first time they're encountered by a user
|
131
|
-
config.start_manually = true
|
132
|
-
|
133
|
-
# whether or not participants will be reset upon conversion
|
134
|
-
#
|
135
|
-
# true participants will only be entered into the experiment once, and the
|
136
|
-
# variant group they belong to is sticky for the duration
|
137
|
-
# false participants will be reset upon conversion and be able to re-enter
|
138
|
-
# the experiment if they encounter it again
|
139
|
-
config.reset_manually = true
|
140
|
-
|
141
|
-
# whether or not to store individual participation when returning a variant
|
142
|
-
#
|
143
|
-
# this can be useful if you are using a custom, content-based algorithm where
|
144
|
-
# the variant is determined by content rather than user bucketing, and you
|
145
|
-
# want to treat participation more like impressions (i.e. for seo experiments)
|
146
|
-
#
|
147
|
-
# true participation is incremented the first time a participant is
|
148
|
-
# enrolled, and the participant is assigned their selection for future
|
149
|
-
# reference, stored via the configured participant adapter
|
150
|
-
# false participation will be incremented every time a variant is returned,
|
151
|
-
# and the participant will not have their assignment stored
|
152
|
-
config.store_participation = true
|
153
|
-
|
154
|
-
# whether or not to enter participants into a variant when using the override
|
155
|
-
# parameter to preview variants
|
156
|
-
#
|
157
|
-
# true using overrides to preview experiments will enter participants into
|
158
|
-
# that variant group
|
159
|
-
# false using overrides to preview experiments will not enter participants
|
160
|
-
# into the experment (won't persist their variant group)
|
161
|
-
config.store_override = false
|
162
|
-
|
163
|
-
# whether or not we track participants when using the override parameter to
|
164
|
-
# preview variants
|
165
|
-
#
|
166
|
-
# true using overrides to preview experiments will increment the
|
167
|
-
# participant count for the override variant
|
168
|
-
# false using overrides to preview experiments will not increment the
|
169
|
-
# participant count for the override variant
|
170
|
-
config.track_override = false
|
171
|
-
|
172
|
-
# whether or not to continue tracking conversions after a winner has been
|
173
|
-
# selected in order to continue monitoring performance of the variant
|
174
|
-
#
|
175
|
-
# true continues to track conversions after a winner has been selected (as
|
176
|
-
# long as the experiment is still running)
|
177
|
-
# false all conversion and participation tracking stops once a winner has
|
178
|
-
# been selected
|
179
|
-
config.track_winner_conversions = false
|
180
|
-
|
181
|
-
# whether or not to allow multiple conversions of the same goal, or default
|
182
|
-
# conversion if no goals are defined
|
183
|
-
#
|
184
|
-
# true tracks multiple participant conversions for the same goal as long
|
185
|
-
# as they haven't been reset (see config.reset_manually)
|
186
|
-
# false prevents tracking multiple conversions for a single participant
|
187
|
-
config.allow_multiple_conversions = false
|
188
|
-
|
189
|
-
# whether or not to allow participants to convert for multiple defined goals
|
190
|
-
#
|
191
|
-
# true allows participants to convert more than one goal as long as they
|
192
|
-
# haven't been reset (see config.reset_manually)
|
193
|
-
# false prevents converting to multiple goals for a single participant
|
194
|
-
config.allow_multiple_goals = false
|
195
|
-
|
196
|
-
# whether or not to enable calibration before an experiment is started - the
|
197
|
-
# participants and conversions will be tracked for your control group while
|
198
|
-
# an experiment remains unstarted, which can be useful for gathering a
|
199
|
-
# baseline conversion rate if you don't already have one
|
200
|
-
#
|
201
|
-
# control is always returned for unstarted experiments by default, and this
|
202
|
-
# configuration only affects whether or not to track metrics
|
203
|
-
#
|
204
|
-
# this setting only applies when start_manually is also true
|
205
|
-
#
|
206
|
-
# true metrics for participation and conversion will be tracked for the
|
207
|
-
# control group until the experiment is started
|
208
|
-
# false metrics will not be tracked while the experiment remains unstarted
|
209
|
-
config.enable_calibration = false
|
210
|
-
|
211
|
-
# whether or not to skip the request filtering for this experiment - can be
|
212
|
-
# useful when defining content-based experiments with custom algorithms which
|
213
|
-
# bucket participants strictly based on additional content metadata and you
|
214
|
-
# want to expose those variants to crawlers and bots
|
215
|
-
#
|
216
|
-
# true requests that would otherwise be filtered based on your
|
217
|
-
# TrailGuide.configuration.request_filter config will instead be
|
218
|
-
# allowed through to this experiment
|
219
|
-
# false default behavior, requests will be filtered based on your config
|
220
|
-
config.skip_request_filter = false
|
221
|
-
|
222
|
-
# whether or not this experiment can be resumed after it's stopped - allows
|
223
|
-
# temporarily "pausing" an experiment then resuming it without losing metrics
|
224
|
-
#
|
225
|
-
# true this experiment can be paused and resumed
|
226
|
-
# false this experiment can only be stopped and reset/restarted
|
227
|
-
config.can_resume = false
|
228
|
-
|
229
|
-
# set a default target sample size for all experiments - this will prevent
|
230
|
-
# metrics and stats from being displayed in the admin UI until the sample size
|
231
|
-
# is reached or the experiment is stopped
|
232
|
-
#
|
233
|
-
# config.target_sample_size = nil
|
234
|
-
|
235
|
-
# callback when connecting to redis fails and trailguide falls back to always
|
236
|
-
# returning control variants
|
237
|
-
config.on_redis_failover = -> (experiment, error) do
|
238
|
-
TrailGuide.logger.error error
|
239
|
-
end
|
240
|
-
|
241
|
-
# callback on experiment start, either manually via UI/console or
|
242
|
-
# automatically depending on config.start_manually, can be used for logging,
|
243
|
-
# tracking, etc.
|
244
|
-
#
|
245
|
-
# context may or may not be present depending on how you're triggering the
|
246
|
-
# action - if you're using the admin, this will be the admin controller
|
247
|
-
# context, if you're in a console you have the option to pass a context to
|
248
|
-
# `experiment.start!` or not
|
249
|
-
#
|
250
|
-
# config.on_start = -> (experiment, context) { ... }
|
251
|
-
|
252
|
-
# callback on experiment schedule manually via UI/console, can be used for logging,
|
253
|
-
# tracking, etc.
|
254
|
-
#
|
255
|
-
# experiments can only be scheduled if config.start_manually is true
|
256
|
-
#
|
257
|
-
# context may or may not be present depending on how you're triggering the
|
258
|
-
# action - if you're using the admin, this will be the admin controller
|
259
|
-
# context, if you're in a console you have the option to pass a context to
|
260
|
-
# `experiment.schedule!` or not
|
261
|
-
#
|
262
|
-
# config.on_schedule = -> (experiment, start_at, stop_at, context) { ... }
|
263
|
-
|
264
|
-
# callback on experiment stop manually via UI/console, can be used for
|
265
|
-
# logging, tracking, etc.
|
266
|
-
#
|
267
|
-
# context may or may not be present depending on how you're triggering the
|
268
|
-
# action - if you're using the admin, this will be the admin controller
|
269
|
-
# context, if you're in a console you have the option to pass a context to
|
270
|
-
# `experiment.stop!` or not
|
271
|
-
#
|
272
|
-
# config.on_stop = -> (experiment, context) { ... }
|
273
|
-
|
274
|
-
# callback on experiment pause manually via UI/console, can be used for
|
275
|
-
# logging, tracking, etc.
|
276
|
-
#
|
277
|
-
# context may or may not be present depending on how you're triggering the
|
278
|
-
# action - if you're using the admin, this will be the admin controller
|
279
|
-
# context, if you're in a console you have the option to pass a context to
|
280
|
-
# `experiment.pause!` or not
|
281
|
-
#
|
282
|
-
# config.on_pause = -> (experiment, context) { ... }
|
283
|
-
|
284
|
-
# callback on experiment resume manually via UI/console, can be used for
|
285
|
-
# logging, tracking, etc.
|
286
|
-
#
|
287
|
-
# context may or may not be present depending on how you're triggering the
|
288
|
-
# action - if you're using the admin, this will be the admin controller
|
289
|
-
# context, if you're in a console you have the option to pass a context to
|
290
|
-
# `experiment.resume!` or not
|
291
|
-
#
|
292
|
-
# config.on_resume = -> (experiment, context) { ... }
|
293
|
-
|
294
|
-
# callback on experiment delete manually via UI/console, can be used for
|
295
|
-
# logging, tracking, etc. - will also be triggered by a reset
|
296
|
-
#
|
297
|
-
# context may or may not be present depending on how you're triggering the
|
298
|
-
# action - if you're using the admin, this will be the admin controller
|
299
|
-
# context, if you're in a console you have the option to pass a context to
|
300
|
-
# `experiment.delete!` or not
|
301
|
-
#
|
302
|
-
# config.on_delete = -> (experiment, context) { ... }
|
303
|
-
|
304
|
-
# callback on experiment reset manually via UI/console, can be used for
|
305
|
-
# logging, tracking, etc. - will also trigger any on_delete callbacks
|
306
|
-
#
|
307
|
-
# context may or may not be present depending on how you're triggering the
|
308
|
-
# action - if you're using the admin, this will be the admin controller
|
309
|
-
# context, if you're in a console you have the option to pass a context to
|
310
|
-
# `experiment.reset!` or not
|
311
|
-
#
|
312
|
-
# config.on_reset = -> (experiment, context) { ... }
|
313
|
-
|
314
|
-
# callback when a winner is selected manually via UI/console, can be used for
|
315
|
-
# logging, tracking, etc.
|
316
|
-
#
|
317
|
-
# context may or may not be present depending on how you're triggering the
|
318
|
-
# action - if you're using the admin, this will be the admin controller
|
319
|
-
# context, if you're in a console you have the option to pass a context to
|
320
|
-
# `experiment.declare_winner!` or not
|
321
|
-
#
|
322
|
-
# config.on_winner = -> (experiment, winner, context) { ... }
|
323
|
-
|
324
|
-
|
325
|
-
# callback when a participant is entered into a variant for the first time,
|
326
|
-
# can be used for logging, tracking, etc.
|
327
|
-
#
|
328
|
-
# config.on_choose = -> (experiment, variant, participant, metadata) { ... }
|
329
|
-
|
330
|
-
# callback every time a participant is returned a variant in the experiment,
|
331
|
-
# can be used for logging, tracking, etc.
|
332
|
-
#
|
333
|
-
# config.on_use = -> (experiment, variant, participant, metadata) { ... }
|
334
|
-
|
335
|
-
# callback when a participant converts for a variant in the experiment, can be
|
336
|
-
# used for logging, tracking, etc.
|
337
|
-
#
|
338
|
-
# config.on_convert = -> (experiment, checkpoint, variant, participant, metadata) { ... }
|
339
|
-
|
340
|
-
|
341
|
-
# callback that can short-circuit participation based on your own logic, which
|
342
|
-
# gets called *after* all the core engine checks (i.e. that the user is
|
343
|
-
# not excluded or already participating, etc.)
|
344
|
-
#
|
345
|
-
# `allowed` will be the value returned by any previous callbacks in the chain
|
346
|
-
#
|
347
|
-
# should return true or false
|
348
|
-
#
|
349
|
-
# config.allow_participation = -> (experiment, allowed, participant, metadata) { ... return true }
|
350
|
-
|
351
|
-
|
352
|
-
# callback that can short-circuit conversion based on your own logic, which
|
353
|
-
# gets called *after* all the core engine checks (i.e. that the user is
|
354
|
-
# participating in the experiment, is within the bounds of the experiment
|
355
|
-
# configuration for allow_multiple_*, etc.)
|
356
|
-
#
|
357
|
-
# `allowed` will be the value returned by any previous callbacks in the chain
|
358
|
-
#
|
359
|
-
# should return true or false
|
360
|
-
#
|
361
|
-
# config.allow_conversion = -> (experiment, allowed, checkpoint, variant, participant, metadata) { ... return true }
|
362
|
-
|
363
|
-
|
364
|
-
# callback that can be used to modify the rollout of a selected winner - for
|
365
|
-
# example you could use a custom algorithm or even something like the flipper
|
366
|
-
# gem to do a "feature rollout" from your control variant to your winner for
|
367
|
-
# all users
|
368
|
-
#
|
369
|
-
# be aware that when using this alongside track_winner_conversions, whatever
|
370
|
-
# variant is returned from this callback chain is what will be tracked for
|
371
|
-
# participation and conversion as long as the experiment is still running
|
372
|
-
#
|
373
|
-
# `winner` will be the variant returned by any previous callbacks in the chain
|
374
|
-
#
|
375
|
-
# must return an experiment variant
|
376
|
-
#
|
377
|
-
# config.rollout_winner = -> (experiment, winner, participant) { ... return variant }
|
378
|
-
end
|
379
|
-
|
380
|
-
# admin ui configuration
|
381
|
-
#
|
382
|
-
TrailGuide::Admin.configure do |config|
|
383
|
-
# display title for admin UI
|
384
|
-
#
|
385
|
-
config.title = 'TrailGuide'
|
386
|
-
|
387
|
-
# display subtitle for admin UI
|
388
|
-
#
|
389
|
-
config.subtitle = 'Experiments and A/B Tests'
|
390
|
-
|
391
|
-
# request parameter can be used to "peek" at results even before an
|
392
|
-
# experiment's target_sample_size has been hit if one is configured
|
393
|
-
#
|
394
|
-
# if you set this to nil, admins will not be able to peek at experiment
|
395
|
-
# results until the target sample size is hit or the experiment is stopped
|
396
|
-
#
|
397
|
-
config.peek_parameter = nil
|
398
|
-
end
|