fiveruns / data_fabric

Sharding support for ActiveRecord 2.x

This URL has Read+Write access

data_fabric / test / thread_test.rb
100644 99 lines (86 sloc) 3.069 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
require File.join(File.dirname(__FILE__), 'test_helper')
require 'erb'
 
class ThreadTest < Test::Unit::TestCase
  
  MUTEX = Mutex.new
 
  if ActiveRecord::VERSION::STRING < '2.2.0'
    def test_concurrency_not_allowed
      assert_raise ArgumentError do
        Object.class_eval %{
class ThreadedEnchilada < ActiveRecord::Base
self.allow_concurrency = true
set_table_name :enchiladas
data_fabric :prefix => 'fiveruns', :replicated => true, :shard_by => :city
end
}
      end
    end
  end
  
  def test_class_and_instance_connections
    Object.class_eval %{
class ThreadedEnchilada < ActiveRecord::Base
set_table_name :enchiladas
data_fabric :prefix => 'fiveruns', :replicated => true, :shard_by => :city
end
}
    ActiveRecord::Base.configurations = load_database_yml
 
    cconn = ThreadedEnchilada.connection
    iconn = ThreadedEnchilada.new.connection
    assert_equal cconn, iconn
  end
  
  def xtest_threaded_access
    clear_databases
 
    filename = File.join(File.dirname(__FILE__), "database.yml")
    ActiveRecord::Base.configurations = load_database_yml
 
    counts = {:austin => 0, :dallas => 0}
    threads = []
    10.times do
      threads << Thread.new do
        begin
          200.times do
            city = rand(1_000_000) % 2 == 0 ? :austin : :dallas
            DataFabric.activate_shard :city => city do
              #puts Enchilada.connection.to_s
              #assert_equal "fiveruns_city_#{city}_test_slave", Enchilada.connection.connection_name
              ThreadedEnchilada.create!(:name => "#{city}")
              MUTEX.synchronize do
                counts[city] += 1
              end
            end
          end
        rescue => e
          puts e.message
          puts e.backtrace.join("\n\t")
        end
      end
    end
    threads.each { |thread| thread.join }
    
    counts.each_pair do |city, count|
      DataFabric.activate_shard(:city => city) do
        # slave should be empty
        #assert_equal "fiveruns_city_#{city}_test_slave", ThreadedEnchilada.connection.connection_name
        assert_equal 0, ThreadedEnchilada.count
        ThreadedEnchilada.transaction do
          #assert_equal "fiveruns_city_#{city}_test_master", Enchilada.connection.connection_name
          # master should have the counts we expect
          assert_equal count, ThreadedEnchilada.count
        end
      end
    end
  end
  
  private
  
  def clear_databases
    ActiveRecord::Base.configurations = { 'test' => { :adapter => 'mysql', :host => 'localhost', :database => 'mysql' } }
    ActiveRecord::Base.establish_connection 'test'
    databases = %w( vr_austin_master vr_austin_slave vr_dallas_master vr_dallas_slave )
    databases.each do |db|
      using_connection do
        execute "use #{db}"
        execute "delete from the_whole_burritos"
      end
    end
    ActiveRecord::Base.clear_active_connections!
  end
  
  def using_connection(&block)
    ActiveRecord::Base.connection.instance_eval(&block)
  end
end