Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/split/experiment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def save
redis.hset(experiment_config_key, :retain_user_alternatives_after_reset, retain_user_alternatives_after_reset)
redis.hset(experiment_config_key, :resettable, resettable)
redis.hset(experiment_config_key, :algorithm, algorithm.to_s)

self
end

Expand Down
2 changes: 2 additions & 0 deletions lib/split/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ def ab_test(metric_descriptor, control = nil, *alternatives)
alternative = if Split.configuration.enabled && !exclude_visitor?
experiment.save
raise(Split::InvalidExperimentsFormatError) unless (Split.configuration.experiments || {}).fetch(experiment.name.to_sym, {})[:combined_experiments].nil?

trial = Trial.new(:user => ab_user, :experiment => experiment,
:override => override_alternative(experiment.name), :exclude => !is_qualified?,
:disabled => split_generically_disabled?)

alt = trial.choose!(self)
alt ? alt.name : nil
else
Expand Down
1 change: 1 addition & 0 deletions lib/split/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Persistence
require 'split/persistence/dual_adapter'
require 'split/persistence/redis_adapter'
require 'split/persistence/session_adapter'
require 'split/persistence/mysql_adapter'

ADAPTERS = {
:cookie => Split::Persistence::CookieAdapter,
Expand Down
90 changes: 90 additions & 0 deletions lib/split/persistence/mysql_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# frozen_string_literal: true
module Split
module Persistence
class MysqlAdapter
DEFAULT_CONFIG = {:namespace => 'persistence'}.freeze

attr_reader :account_id

def initialize(context, acc_id = nil)
# Split::Persistence.adapter.new(nil, 347381).test_create_or_update('exp123:1', 'control')
if acc_id
@account_id = acc_id
elsif lookup_by = self.class.config[:lookup_by]
if lookup_by.respond_to?(:call)
key_frag = lookup_by.call(context)
else
key_frag = context.send(lookup_by)
end
@account_id = key_frag
else
raise "Please configure lookup_by"
end
end

#--------------

def test_get(property)
search_for_record(property)
end

def test_create_or_update(property, value)
record = Manage::ExperimentPersistence.where(
experiment_id: experiment_id_parser(property),
account_id: account_id,
property: property
).first_or_initialize
record.update!(value: value)
end

#-------------

def [](property)
search_for_record(property)
end

def []=(property, value)
record = Manage::ExperimentPersistence.where(
experiment_id: experiment_id_parser(property),
account_id: account_id,
property: property
).first_or_initialize
record.update!(value: value)
end

def delete(field)
record_to_delete = search_for_record(property)
record_to_delete.destroy!
end

# --------

def keys
Split.redis.hkeys(redis_key)
end

def self.with_config(options={})
self.config.merge!(options)
self
end

def self.config
@config ||= DEFAULT_CONFIG.dup
end

def self.reset_config!
@config = DEFAULT_CONFIG.dup
end

def experiment_id_parser(property)
property.split(":").first
end

def search_for_record(property)
Manage::ExperimentPersistence.find_by(experiment_id: experiment_id_parser(property), property: property, account_id: account_id)
end


end
end
end
2 changes: 1 addition & 1 deletion lib/split/redis_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def make_list_length(list_name, new_length)

def add_to_set(set_name, value)
redis.sadd(set_name, value) unless redis.sismember(set_name, value)
end
end``

private

Expand Down
10 changes: 9 additions & 1 deletion lib/split/trial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ def complete!(context = nil)
# method is guaranteed to only run once, and will skip the alternative choosing process if run
# a second time.
def choose!(context = nil)

@user.cleanup_old_experiments!
# Only run the process once

return alternative if @alternative_choosen


user_experiment_key = @experiment.retain_user_alternatives_after_reset ? @user.alternative_key_for_experiment(@experiment) : @experiment.key
new_participant = @user[user_experiment_key].nil?
if override_is_alternative?

self.alternative = @options[:override]
if should_store_alternative? && !@user[user_experiment_key]
self.alternative.increment_participation
Expand All @@ -72,11 +76,11 @@ def choose!(context = nil)
self.alternative = @experiment.winner
else
cleanup_old_versions unless experiment.retain_user_alternatives_after_reset

if exclude_user?
self.alternative = @experiment.control
else
self.alternative = @user[user_experiment_key]

if alternative.nil?
if @experiment.cohorting_disabled?
self.alternative = @experiment.control
Expand All @@ -87,17 +91,21 @@ def choose!(context = nil)
self.alternative.increment_participation

save_time_that_user_is_assigned

run_callback context, Split.configuration.on_trial_choose
end
end
end
end


new_participant_and_cohorting_disabled = new_participant && @experiment.cohorting_disabled?

@user[user_experiment_key] = alternative.name unless @experiment.has_winner? || !should_store_alternative? || new_participant_and_cohorting_disabled

@alternative_choosen = true
run_callback context, Split.configuration.on_trial unless @options[:disabled] || Split.configuration.disabled? || new_participant_and_cohorting_disabled

alternative
end

Expand Down