public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Add synchronization to connection pool also
Nick (author)
Sat Apr 19 12:42:56 -0700 2008
commit  cab76ce6ac2983f59451e2d53b23746a2873aea0
tree    9aeb8c88ac13d353660d147fb82e6b865700f45a
parent  50cd4bdc99ebaf3ac879e4e7fea43c5b55ca5f68
...
12
13
14
 
 
 
15
16
17
...
70
71
72
73
 
74
75
76
...
82
83
84
 
85
86
87
...
89
90
91
92
 
93
94
95
96
 
97
98
99
100
101
 
 
 
 
102
103
104
...
12
13
14
15
16
17
18
19
20
...
73
74
75
 
76
77
78
79
...
85
86
87
88
89
90
91
...
93
94
95
 
96
97
98
99
 
100
101
102
103
104
105
106
107
108
109
110
111
112
0
@@ -12,6 +12,9 @@ module ActiveRecord
0
 
0
         # The ConnectionSpecification for this pool
0
         @spec = spec
0
+
0
+        # The mutex used to synchronize pool access
0
+        @connection_mutex = Monitor.new
0
       end
0
 
0
       def active_connection_name #:nodoc:
0
@@ -70,7 +73,7 @@ module ActiveRecord
0
           # Verify the connection.
0
           conn.verify!(verification_timeout)
0
         else
0
-          self.connection = spec
0
+          self.set_connection spec
0
           conn = active_connections[name]
0
         end
0
 
0
@@ -82,6 +85,7 @@ module ActiveRecord
0
         active_connections[active_connection_name] ? true : false
0
       end
0
 
0
+      # Disconnect all connections in the pool.
0
       def disconnect!
0
         clear_cache!(@active_connections) do |name, conn|
0
           conn.disconnect!
0
@@ -89,16 +93,20 @@ module ActiveRecord
0
       end
0
 
0
       # Set the connection for the class.
0
-      def connection=(spec) #:nodoc:
0
+      def set_connection(spec) #:nodoc:
0
         if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
0
           active_connections[active_connection_name] = spec
0
         elsif spec.kind_of?(ActiveRecord::Base::ConnectionSpecification)
0
-          self.connection = ActiveRecord::Base.send(spec.adapter_method, spec.config)
0
+          self.set_connection ActiveRecord::Base.send(spec.adapter_method, spec.config)
0
         else
0
           raise ConnectionNotEstablished
0
         end
0
       end
0
 
0
+      synchronize :active_connection, :connection, :clear_active_connections!,
0
+        :clear_reloadable_connections!, :verify_active_connections!, :retrieve_connection,
0
+        :connected?, :disconnect!, :set_connection, :with => :@connection_mutex
0
+
0
       private
0
         def clear_cache!(cache, &block)
0
           cache.each(&block) if block_given?
...
27
28
29
 
 
30
31
32
...
37
38
39
40
 
41
42
43
...
27
28
29
30
31
32
33
34
...
39
40
41
 
42
43
44
45
0
@@ -27,6 +27,8 @@ module ActiveRecord
0
     @@connection_pools = {}
0
 
0
     class << self
0
+      # Turning on allow_concurrency basically switches a null mutex for a real one, so that
0
+      # multi-threaded access of the connection pools hash is synchronized.
0
       def allow_concurrency=(flag)
0
         if @@allow_concurrency != flag
0
           if flag
0
@@ -37,7 +39,7 @@ module ActiveRecord
0
         end
0
       end
0
 
0
-      # for internal use only
0
+      # for internal use only and for testing
0
       def active_connections #:nodoc:
0
         @@connection_pools.inject({}) do |hash,kv|
0
           hash[kv.first] = kv.last.active_connection
...
18
19
20
21
 
22
23
24
...
26
27
28
29
 
30
31
32
...
18
19
20
 
21
22
23
24
...
26
27
28
 
29
30
31
32
0
@@ -18,7 +18,7 @@ class Module
0
       raise ArgumentError, "Synchronization needs a mutex. Supply an options hash with a :with key as the last argument (e.g. synchronize :hello, :with => :@mutex)."
0
     end
0
 
0
-    methods.each do |method|
0
+    methods.flatten.each do |method|
0
       aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
0
       if instance_methods.include?("#{aliased_method}_without_synchronization#{punctuation}")
0
         raise ArgumentError, "#{method} is already synchronized. Double synchronization is not currently supported."
0
@@ -26,7 +26,7 @@ class Module
0
       module_eval(<<-EOS, __FILE__, __LINE__)
0
         def #{aliased_method}_with_synchronization#{punctuation}(*args, &block)
0
           #{with}.synchronize do
0
-            #{aliased_method}_without_synchronization#{punctuation}(*args,&block)
0
+            #{aliased_method}_without_synchronization#{punctuation}(*args, &block)
0
           end
0
         end
0
       EOS

Comments