Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Lessen chance of Abingo creating multiple copies of an experiment whe…

…n experiment is run in highly concurrent environments. (i.e. lots of Mongrels all racing to create at the same time). Not perfect yet.
  • Loading branch information...
commit dede339e5e4b2f2395e7df650941251ba064598a 1 parent 25b5de3
Patrick McKenzie authored
Showing with 29 additions and 4 deletions.
  1. +2 −2 README
  2. +9 −0 lib/abingo.rb
  3. +18 −2 test/abingo_test.rb
View
4 README
@@ -1,4 +1,4 @@
-A/Bingo Version 1.0.1
+A/Bingo Version 1.0.0
======
Rails A/B testing. One minute to install. One line to set up a new A/B test.
@@ -106,4 +106,4 @@ A/Bingo defaults to using the same cache store as Rails. If you want to change
Abingo.cache = ActiveSupport::Cache::MemCacheStore.new("cache.example.com:12345") #best if really memcacheDB
-Copyright (c) 2009-2010 Patrick McKenzie, released under the MIT license
+Copyright (c) 2009-2010 Patrick McKenzie, released under the MIT license
View
9 lib/abingo.rb
@@ -73,8 +73,17 @@ def self.test(test_name, alternatives, options = {})
end
unless Abingo::Experiment.exists?(test_name)
+ lock_key = test_name.gsub(" ", "_")
+ if Abingo.cache.exist?(lock_key)
+ while Abingo.cache.exist?(lock_key)
+ sleep(0.1)
+ end
+ break
+ end
+ Abingo.cache.write(lock_key, 1, :expires_in => 5.seconds)
conversion_name = options[:conversion] || options[:conversion_name]
Abingo::Experiment.start_experiment!(test_name, self.parse_alternatives(alternatives), conversion_name)
+ Abingo.cache.delete(lock_key)
end
choice = self.find_alternative_for_user(test_name, alternatives)
View
20 test/abingo_test.rb
@@ -30,8 +30,8 @@ class AbingoTest < ActiveSupport::TestCase
end
test "exists works right" do
- Abingo.test("exist words right", %w{does does_not})
- assert Abingo::Experiment.exists?("exist words right")
+ Abingo.test("exist works right", %w{does does_not})
+ assert Abingo::Experiment.exists?("exist works right")
end
test "alternatives picked consistently" do
@@ -116,4 +116,20 @@ class AbingoTest < ActiveSupport::TestCase
ex.reload
assert_equal 1, ex.participants #Original identity counted, new identity not counted b/c test stopped
end
+
+ test "proper experiment creation in high concurrency" do
+ conversion_name = "purchase"
+ test_name = "high_concurrency_test"
+ alternatives = %w{foo bar}
+
+ threads = []
+ 5.times do
+ threads << Thread.new do
+ Abingo.test(test_name, alternatives, conversion_name)
+ 1
+ end
+ end
+ sleep(10)
+ assert_equal 1, Abingo::Experiment.count_by_sql(["select count(id) from experiments where test_name = ?", test_name])
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.