lib/split/experiment.rb in split-3.3.2 vs lib/split/experiment.rb in split-3.4.0
- old
+ new
@@ -1,16 +1,16 @@
# frozen_string_literal: true
module Split
class Experiment
attr_accessor :name
- attr_writer :algorithm
- attr_accessor :resettable
attr_accessor :goals
- attr_accessor :alternatives
attr_accessor :alternative_probabilities
attr_accessor :metadata
+ attr_reader :alternatives
+ attr_reader :resettable
+
DEFAULT_OPTIONS = {
:resettable => true
}
def initialize(name, options = {})
@@ -23,11 +23,11 @@
if alternatives.empty? && (exp_config = Split.configuration.experiment_for(name))
options = {
alternatives: load_alternatives_from_configuration,
goals: Split::GoalsCollection.new(@name).load_from_configuration,
metadata: load_metadata_from_configuration,
- resettable: exp_config[:resettable],
+ resettable: exp_config.fetch(:resettable, true),
algorithm: exp_config[:algorithm]
}
else
options[:alternatives] = alternatives
end
@@ -60,11 +60,11 @@
exp_config = Split.configuration.experiment_for(name)
if exp_config
alts = load_alternatives_from_configuration
options[:goals] = Split::GoalsCollection.new(@name).load_from_configuration
options[:metadata] = load_metadata_from_configuration
- options[:resettable] = exp_config[:resettable]
+ options[:resettable] = exp_config.fetch(:resettable, true)
options[:algorithm] = exp_config[:algorithm]
end
end
options[:alternatives] = alts
@@ -79,16 +79,16 @@
def save
validate!
if new_record?
start unless Split.configuration.start_manually
+ persist_experiment_configuration
elsif experiment_configuration_has_changed?
reset unless Split.configuration.reset_manually
+ persist_experiment_configuration
end
- persist_experiment_configuration if new_record? || experiment_configuration_has_changed?
-
redis.hset(experiment_config_key, :resettable, resettable)
redis.hset(experiment_config_key, :algorithm, algorithm.to_s)
self
end
@@ -142,15 +142,17 @@
nil
end
end
def has_winner?
- !winner.nil?
+ return @has_winner if defined? @has_winner
+ @has_winner = !winner.nil?
end
def winner=(winner_name)
redis.hset(:experiment_winner, name, winner_name.to_s)
+ @has_winner = true
end
def participant_count
alternatives.inject(0){|sum,a| sum + a.participant_count}
end
@@ -159,10 +161,11 @@
alternatives.first
end
def reset_winner
redis.hdel(:experiment_winner, name)
+ @has_winner = false
end
def start
redis.hset(:experiment_start_times, @name, Time.now.to_i)
end
@@ -418,18 +421,26 @@
alts.flatten
end
end
def load_alternatives_from_redis
- case redis.type(@name)
- when 'set' # convert legacy sets to lists
- alts = redis.smembers(@name)
- redis.del(@name)
- alts.reverse.each {|a| redis.lpush(@name, a) }
- redis.lrange(@name, 0, -1)
- else
- redis.lrange(@name, 0, -1)
+ alternatives = case redis.type(@name)
+ when 'set' # convert legacy sets to lists
+ alts = redis.smembers(@name)
+ redis.del(@name)
+ alts.reverse.each {|a| redis.lpush(@name, a) }
+ redis.lrange(@name, 0, -1)
+ else
+ redis.lrange(@name, 0, -1)
+ end
+ alternatives.map do |alt|
+ alt = begin
+ JSON.parse(alt)
+ rescue
+ alt
+ end
+ Split::Alternative.new(alt, @name)
end
end
private
@@ -441,11 +452,11 @@
RedisInterface.new
end
def persist_experiment_configuration
redis_interface.add_to_set(:experiments, name)
- redis_interface.persist_list(name, @alternatives.map(&:name))
+ redis_interface.persist_list(name, @alternatives.map{|alt| {alt.name => alt.weight}.to_json})
goals_collection.save
redis.set(metadata_key, @metadata.to_json) unless @metadata.nil?
end
def remove_experiment_configuration
@@ -457,10 +468,10 @@
def experiment_configuration_has_changed?
existing_alternatives = load_alternatives_from_redis
existing_goals = Split::GoalsCollection.new(@name).load_from_redis
existing_metadata = load_metadata_from_redis
- existing_alternatives != @alternatives.map(&:name) ||
+ existing_alternatives.map(&:to_s) != @alternatives.map(&:to_s) ||
existing_goals != @goals ||
existing_metadata != @metadata
end
def goals_collection