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