Module: Split::Helper

Included in:
EncapsulatedHelper::ContextShim
Defined in:
lib/split/helper.rb

Class Method Summary collapse

Class Method Details

.ab_finished(metric_descriptor, options = {:reset => true}) ⇒ Object


62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/split/helper.rb', line 62

def ab_finished(metric_descriptor, options = {: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|
      finish_experiment(experiment, options.merge(:goals => goals))
    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


6
7
8
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
# File 'lib/split/helper.rb', line 6

def ab_test(metric_descriptor, control = nil, *alternatives)
  begin
    experiment = ExperimentCatalog.find_or_initialize(metric_descriptor, control, *alternatives)
    alternative = if Split.configuration.enabled
      experiment.save
      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?
     = trial ? trial. : {}
    yield(alternative, )
  else
    alternative
  end
end

.ab_userObject


101
102
103
# File 'lib/split/helper.rb', line 101

def ab_user
  @ab_user ||= User.new(self)
end

.active_experimentsObject


122
123
124
# File 'lib/split/helper.rb', line 122

def active_experiments
  ab_user.active_experiments
end

.begin_experiment(experiment, alternative_name = nil) ⇒ Object


94
95
96
97
98
99
# File 'lib/split/helper.rb', line 94

def begin_experiment(experiment, alternative_name = nil)
  warn 'DEPRECATION WARNING: begin_experiment is deprecated and will be removed from Split 2.0.0'
  alternative_name ||= experiment.control.name
  ab_user[experiment.key] = alternative_name
  alternative_name
end

.control_variable(control) ⇒ Object


137
138
139
# File 'lib/split/helper.rb', line 137

def control_variable(control)
  Hash === control ? control.keys.first.to_s : control.to_s
end

.exclude_visitor?Boolean

Returns:

  • (Boolean)

105
106
107
# File 'lib/split/helper.rb', line 105

def exclude_visitor?
  instance_eval(&Split.configuration.ignore_filter) || is_ignored_ip_address? || is_robot?
end

.finish_experiment(experiment, options = {:reset => true}) ⇒ Object


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/split/helper.rb', line 43

def finish_experiment(experiment, options = {:reset => true})
  return true if experiment.has_winner?
  should_reset = experiment.resettable? && options[:reset]
  if ab_user[experiment.finished_key] && !should_reset
    return true
  else
    alternative_name = ab_user[experiment.key]
    trial = Trial.new(:user => ab_user, :experiment => experiment,
          :alternative => alternative_name)
    trial.complete!(options[:goals], self)

    if should_reset
      reset!(experiment)
    else
      ab_user[experiment.finished_key] = true
    end
  end
end

.finished(metric_descriptor, options = {:reset => true}) ⇒ Object


77
78
79
80
# File 'lib/split/helper.rb', line 77

def finished(metric_descriptor, options = {:reset => true})
  warn 'DEPRECATION WARNING: finished method was renamed to ab_finished and will be removed in Split 2.0.0'
  ab_finished(metric_descriptor, options)
end

.is_ignored_ip_address?Boolean

Returns:

  • (Boolean)

113
114
115
116
117
118
119
120
# File 'lib/split/helper.rb', line 113

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 defined?(request) && (request.ip == ip || (ip.class == Regexp && request.ip =~ ip))
  end
  false
end

.is_robot?Boolean

Returns:

  • (Boolean)

109
110
111
# File 'lib/split/helper.rb', line 109

def is_robot?
  defined?(request) && request.user_agent =~ Split.configuration.robot_regex
end

.normalize_metric(metric_descriptor) ⇒ Object


126
127
128
129
130
131
132
133
134
135
# File 'lib/split/helper.rb', line 126

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


86
87
88
# File 'lib/split/helper.rb', line 86

def override_alternative(experiment_name)
  params[experiment_name] if override_present?(experiment_name)
end

.override_present?(experiment_name) ⇒ Boolean

Returns:

  • (Boolean)

82
83
84
# File 'lib/split/helper.rb', line 82

def override_present?(experiment_name)
  defined?(params) && params[experiment_name]
end

.reset!(experiment) ⇒ Object


39
40
41
# File 'lib/split/helper.rb', line 39

def reset!(experiment)
  ab_user.delete(experiment.key)
end

.split_generically_disabled?Boolean

Returns:

  • (Boolean)

90
91
92
# File 'lib/split/helper.rb', line 90

def split_generically_disabled?
  defined?(params) && params['SPLIT_DISABLE']
end