Module: Split::Helper
- Included in:
- EncapsulatedHelper::ContextShim
- Defined in:
- lib/split/helper.rb
Constant Summary collapse
- OVERRIDE_PARAM_NAME =
"ab_test"
Class Method Summary collapse
- .ab_active_experiments ⇒ Object
- .ab_finished(metric_descriptor, options = { reset: true }) ⇒ Object
- .ab_record_extra_info(metric_descriptor, key, value = 1) ⇒ Object
- .ab_test(metric_descriptor, control = nil, *alternatives) ⇒ Object
- .ab_user ⇒ Object
- .active_experiments ⇒ Object
- .control_variable(control) ⇒ Object
- .exclude_visitor? ⇒ Boolean
- .finish_experiment(experiment, options = { reset: true }) ⇒ Object
- .is_ignored_ip_address? ⇒ Boolean
- .is_preview? ⇒ Boolean
- .is_robot? ⇒ Boolean
- .normalize_metric(metric_descriptor) ⇒ Object
- .override_alternative(experiment_name) ⇒ Object
- .override_alternative_by_cookies(experiment_name) ⇒ Object
- .override_alternative_by_params(experiment_name) ⇒ Object
- .override_present?(experiment_name) ⇒ Boolean
- .params_present? ⇒ Boolean
- .request_present? ⇒ Boolean
- .reset!(experiment) ⇒ Object
- .split_generically_disabled? ⇒ Boolean
Class Method Details
.ab_active_experiments ⇒ Object
108 109 110 111 112 113 |
# File 'lib/split/helper.rb', line 108 def ab_active_experiments ab_user.active_experiments rescue => e raise unless Split.configuration.db_failover Split.configuration.db_failover_on_db_error.call(e) end |
.ab_finished(metric_descriptor, options = { reset: true }) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/split/helper.rb', line 72 def ab_finished(metric_descriptor, = { reset: true }) return if exclude_visitor? || Split.configuration.disabled? metric_descriptor, goals = normalize_metric(metric_descriptor) experiments = Metric.possible_experiments(metric_descriptor) if experiments.any? experiments.each do |experiment| next if override_present?(experiment.key) finish_experiment(experiment, .merge(goals: goals)) end end rescue => e raise unless Split.configuration.db_failover Split.configuration.db_failover_on_db_error.call(e) end |
.ab_record_extra_info(metric_descriptor, key, value = 1) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/split/helper.rb', line 88 def ab_record_extra_info(metric_descriptor, key, value = 1) return if exclude_visitor? || Split.configuration.disabled? || value.nil? metric_descriptor, _ = normalize_metric(metric_descriptor) experiments = Metric.possible_experiments(metric_descriptor) if experiments.any? experiments.each do |experiment| alternative_name = ab_user[experiment.key] if alternative_name alternative = experiment.alternatives.find { |alt| alt.name == alternative_name } alternative.record_extra_info(key, value) if alternative end end end rescue => e raise unless Split.configuration.db_failover Split.configuration.db_failover_on_db_error.call(e) end |
.ab_test(metric_descriptor, control = nil, *alternatives) ⇒ Object
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 |
# File 'lib/split/helper.rb', line 9 def ab_test(metric_descriptor, control = nil, *alternatives) begin experiment = ExperimentCatalog.find_or_initialize(metric_descriptor, control, *alternatives) alternative = if Split.configuration.enabled && !exclude_visitor? experiment.save raise(Split::InvalidExperimentsFormatError) unless (Split.configuration.experiments || {}).fetch(experiment.name.to_sym, {})[:combined_experiments].nil? trial = Trial.new(user: ab_user, experiment: experiment, override: override_alternative(experiment.name), exclude: exclude_visitor?, disabled: split_generically_disabled?) alt = trial.choose!(self) alt ? alt.name : nil else control_variable(experiment.control) end rescue Errno::ECONNREFUSED, Redis::BaseError, SocketError => e raise(e) unless Split.configuration.db_failover Split.configuration.db_failover_on_db_error.call(e) if Split.configuration.db_failover_allow_parameter_override alternative = override_alternative(experiment.name) if override_present?(experiment.name) alternative = control_variable(experiment.control) if split_generically_disabled? end ensure alternative ||= control_variable(experiment.control) end if block_given? = experiment.[alternative] if experiment. yield(alternative, || {}) else alternative end end |
.ab_user ⇒ Object
140 141 142 |
# File 'lib/split/helper.rb', line 140 def ab_user @ab_user ||= User.new(self) end |
.active_experiments ⇒ Object
173 174 175 |
# File 'lib/split/helper.rb', line 173 def active_experiments ab_user.active_experiments end |
.control_variable(control) ⇒ Object
188 189 190 |
# File 'lib/split/helper.rb', line 188 def control_variable(control) Hash === control ? control.keys.first.to_s : control.to_s end |
.exclude_visitor? ⇒ Boolean
144 145 146 |
# File 'lib/split/helper.rb', line 144 def exclude_visitor? request_present? && (instance_exec(request, &Split.configuration.ignore_filter) || is_ignored_ip_address? || is_robot? || is_preview?) end |
.finish_experiment(experiment, options = { reset: true }) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/split/helper.rb', line 47 def finish_experiment(experiment, = { reset: true }) return false if active_experiments[experiment.name].nil? return true if experiment.has_winner? should_reset = experiment.resettable? && [:reset] if ab_user[experiment.finished_key] && !should_reset true else alternative_name = ab_user[experiment.key] trial = Trial.new( user: ab_user, experiment: experiment, alternative: alternative_name, goals: [:goals], ) trial.complete!(self) if should_reset reset!(experiment) else ab_user[experiment.finished_key] = true end end end |
.is_ignored_ip_address? ⇒ Boolean
156 157 158 159 160 161 162 163 |
# File 'lib/split/helper.rb', line 156 def is_ignored_ip_address? return false if Split.configuration.ignore_ip_addresses.empty? Split.configuration.ignore_ip_addresses.each do |ip| return true if request_present? && (request.ip == ip || (ip.class == Regexp && request.ip =~ ip)) end false end |
.is_preview? ⇒ Boolean
152 153 154 |
# File 'lib/split/helper.rb', line 152 def is_preview? request_present? && defined?(request.headers) && request.headers["x-purpose"] == "preview" end |
.is_robot? ⇒ Boolean
148 149 150 |
# File 'lib/split/helper.rb', line 148 def is_robot? request_present? && request.user_agent =~ Split.configuration.robot_regex end |
.normalize_metric(metric_descriptor) ⇒ Object
177 178 179 180 181 182 183 184 185 186 |
# File 'lib/split/helper.rb', line 177 def normalize_metric(metric_descriptor) if Hash === metric_descriptor experiment_name = metric_descriptor.keys.first goals = Array(metric_descriptor.values.first) else experiment_name = metric_descriptor goals = [] end return experiment_name, goals end |
.override_alternative(experiment_name) ⇒ Object
119 120 121 |
# File 'lib/split/helper.rb', line 119 def override_alternative(experiment_name) override_alternative_by_params(experiment_name) || (experiment_name) end |
.override_alternative_by_cookies(experiment_name) ⇒ Object
127 128 129 130 131 132 133 134 |
# File 'lib/split/helper.rb', line 127 def (experiment_name) return unless request_present? if request. && request..key?("split_override") experiments = JSON.parse(request.["split_override"]) rescue {} experiments[experiment_name] end end |
.override_alternative_by_params(experiment_name) ⇒ Object
123 124 125 |
# File 'lib/split/helper.rb', line 123 def override_alternative_by_params(experiment_name) params_present? && params[OVERRIDE_PARAM_NAME] && params[OVERRIDE_PARAM_NAME][experiment_name] end |
.override_present?(experiment_name) ⇒ Boolean
115 116 117 |
# File 'lib/split/helper.rb', line 115 def override_present?(experiment_name) override_alternative_by_params(experiment_name) || (experiment_name) end |
.params_present? ⇒ Boolean
165 166 167 |
# File 'lib/split/helper.rb', line 165 def params_present? defined?(params) && params end |
.request_present? ⇒ Boolean
169 170 171 |
# File 'lib/split/helper.rb', line 169 def request_present? defined?(request) && request end |
.reset!(experiment) ⇒ Object
43 44 45 |
# File 'lib/split/helper.rb', line 43 def reset!(experiment) ab_user.delete(experiment.key) end |
.split_generically_disabled? ⇒ Boolean
136 137 138 |
# File 'lib/split/helper.rb', line 136 def split_generically_disabled? params_present? && params["SPLIT_DISABLE"] end |