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