lib/split/experiment.rb in split-1.1.0 vs lib/split/experiment.rb in split-1.2.0
- old
+ new
@@ -4,10 +4,11 @@
attr_writer :algorithm
attr_accessor :resettable
attr_accessor :goals
attr_accessor :alternatives
attr_accessor :alternative_probabilities
+ attr_accessor :metadata
DEFAULT_OPTIONS = {
:resettable => true
}
@@ -20,17 +21,19 @@
if alternatives.empty? && (exp_config = Split.configuration.experiment_for(name))
set_alternatives_and_options(
alternatives: load_alternatives_from_configuration,
goals: load_goals_from_configuration,
+ metadata: load_metadata_from_configuration,
resettable: exp_config[:resettable],
algorithm: exp_config[:algorithm]
)
else
set_alternatives_and_options(
alternatives: alternatives,
goals: options[:goals],
+ metadata: options[:metadata],
resettable: options[:resettable],
algorithm: options[:algorithm]
)
end
end
@@ -38,10 +41,11 @@
def set_alternatives_and_options(options)
self.alternatives = options[:alternatives]
self.goals = options[:goals]
self.resettable = options[:resettable]
self.algorithm = options[:algorithm]
+ self.metadata = options[:metadata]
end
def extract_alternatives_from_options(options)
alts = options[:alternatives] || []
@@ -54,10 +58,11 @@
if alts.empty?
exp_config = Split.configuration.experiment_for(name)
if exp_config
alts = load_alternatives_from_configuration
options[:goals] = load_goals_from_configuration
+ options[:metadata] = load_metadata_from_configuration
options[:resettable] = exp_config[:resettable]
options[:algorithm] = exp_config[:algorithm]
end
end
@@ -77,20 +82,24 @@
if new_record?
Split.redis.sadd(:experiments, name)
start unless Split.configuration.start_manually
@alternatives.reverse.each {|a| Split.redis.lpush(name, a.name)}
@goals.reverse.each {|a| Split.redis.lpush(goals_key, a)} unless @goals.nil?
+ Split.redis.set(metadata_key, @metadata.to_json) unless @metadata.nil?
else
existing_alternatives = load_alternatives_from_redis
existing_goals = load_goals_from_redis
- unless existing_alternatives == @alternatives.map(&:name) && existing_goals == @goals
+ existing_metadata = load_metadata_from_redis
+ unless existing_alternatives == @alternatives.map(&:name) && existing_goals == @goals && existing_metadata == @metadata
reset
@alternatives.each(&:delete)
delete_goals
+ delete_metadata
Split.redis.del(@name)
@alternatives.reverse.each {|a| Split.redis.lpush(name, a.name)}
@goals.reverse.each {|a| Split.redis.lpush(goals_key, a)} unless @goals.nil?
+ Split.redis.set(metadata_key, @metadata.to_json) unless @metadata.nil?
end
end
Split.redis.hset(experiment_config_key, :resettable, resettable)
Split.redis.hset(experiment_config_key, :algorithm, algorithm.to_s)
@@ -219,10 +228,14 @@
def finished_key
"#{key}:finished"
end
+ def metadata_key
+ "#{name}:metadata"
+ end
+
def resettable?
resettable
end
def reset
@@ -236,24 +249,30 @@
alternatives.each(&:delete)
reset_winner
Split.redis.srem(:experiments, name)
Split.redis.del(name)
delete_goals
+ delete_metadata
Split.configuration.on_experiment_delete.call(self)
increment_version
end
def delete_goals
Split.redis.del(goals_key)
end
+ def delete_metadata
+ Split.redis.del(metadata_key)
+ end
+
def load_from_redis
exp_config = Split.redis.hgetall(experiment_config_key)
self.resettable = exp_config['resettable']
self.algorithm = exp_config['algorithm']
self.alternatives = load_alternatives_from_redis
self.goals = load_goals_from_redis
+ self.metadata = load_metadata_from_redis
end
def calc_winning_alternatives
if goals.empty?
self.estimate_winning_alternative
@@ -386,10 +405,14 @@
def experiment_config_key
"experiment_configurations/#{@name}"
end
+ def load_metadata_from_configuration
+ metadata = Split.configuration.experiment_for(@name)[:metadata]
+ end
+
def load_goals_from_configuration
goals = Split.configuration.experiment_for(@name)[:goals]
if goals.nil?
goals = []
else
@@ -397,9 +420,14 @@
end
end
def load_goals_from_redis
Split.redis.lrange(goals_key, 0, -1)
+ end
+
+ def load_metadata_from_redis
+ meta = Split.redis.get(metadata_key)
+ JSON.parse(meta) unless meta.nil?
end
def load_alternatives_from_configuration
alts = Split.configuration.experiment_for(@name)[:alternatives]
raise ArgumentError, "Experiment configuration is missing :alternatives array" unless alts