def self.test(test_name, alternatives, options = {})
ABingoCampingPlugin.logger.debug "test #{test_name} alternatives: #{alternatives.inspect} options:#{options.inspect} for #{Abingo.identity}"
short_circuit = Abingo.cache.read("Abingo::Experiment::short_circuit(#{test_name})".gsub(" ", "_"))
unless short_circuit.nil?
return short_circuit
end
unless ABingoCampingPlugin::Models::Experiment.exists?(test_name)
lock_key = "Abingo::lock_for_creation(#{test_name.gsub(" ", "_")})"
creation_required = true
if Abingo.cache.exist?(lock_key)
creation_required = false
while Abingo.cache.exist?(lock_key)
sleep(0.1)
end
creation_required = ABingoCampingPlugin::Models::Experiment.exists?(test_name)
end
if creation_required
Abingo.cache.write(lock_key, 1, :expires_in => 5.seconds)
conversion_name = options[:conversion] || options[:conversion_name]
ABingoCampingPlugin::Models::Experiment.start_experiment!(test_name, self.parse_alternatives(alternatives), conversion_name)
Abingo.cache.delete(lock_key)
end
end
choice = self.find_alternative_for_user(test_name, alternatives)
participating_tests = Abingo.cache.read("Abingo::participating_tests::#{Abingo.identity}") || []
if options[:multiple_participation] || !(participating_tests.include?(test_name))
unless participating_tests.include?(test_name)
participating_tests = participating_tests + [test_name]
expires_in = Abingo.expires_in
if expires_in
Abingo.cache.write("Abingo::participating_tests::#{Abingo.identity}", participating_tests, {:expires_in => expires_in})
else
Abingo.cache.write("Abingo::participating_tests::#{Abingo.identity}", participating_tests)
end
end
if (!@@options[:count_humans_only] || Abingo.is_human?)
ABingoCampingPlugin::Models::Alternative.score_participation(test_name)
end
end
if block_given?
yield(choice)
else
choice
end
end