aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick <nick@nicksieger.com>2008-04-19 14:42:56 -0500
committerNick Sieger <nick@nicksieger.com>2008-08-29 14:12:09 -0500
commitcab76ce6ac2983f59451e2d53b23746a2873aea0 (patch)
tree9aeb8c88ac13d353660d147fb82e6b865700f45a
parent50cd4bdc99ebaf3ac879e4e7fea43c5b55ca5f68 (diff)
downloadrails-cab76ce6ac2983f59451e2d53b23746a2873aea0.tar.gz
rails-cab76ce6ac2983f59451e2d53b23746a2873aea0.tar.bz2
rails-cab76ce6ac2983f59451e2d53b23746a2873aea0.zip
Add synchronization to connection pool also
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/synchronization.rb4
3 files changed, 16 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 8f241a39ca..2d13d02fad 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -12,6 +12,9 @@ module ActiveRecord
# The ConnectionSpecification for this pool
@spec = spec
+
+ # The mutex used to synchronize pool access
+ @connection_mutex = Monitor.new
end
def active_connection_name #:nodoc:
@@ -70,7 +73,7 @@ module ActiveRecord
# Verify the connection.
conn.verify!(verification_timeout)
else
- self.connection = spec
+ self.set_connection spec
conn = active_connections[name]
end
@@ -82,6 +85,7 @@ module ActiveRecord
active_connections[active_connection_name] ? true : false
end
+ # Disconnect all connections in the pool.
def disconnect!
clear_cache!(@active_connections) do |name, conn|
conn.disconnect!
@@ -89,16 +93,20 @@ module ActiveRecord
end
# Set the connection for the class.
- def connection=(spec) #:nodoc:
+ def set_connection(spec) #:nodoc:
if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
active_connections[active_connection_name] = spec
elsif spec.kind_of?(ActiveRecord::Base::ConnectionSpecification)
- self.connection = ActiveRecord::Base.send(spec.adapter_method, spec.config)
+ self.set_connection ActiveRecord::Base.send(spec.adapter_method, spec.config)
else
raise ConnectionNotEstablished
end
end
+ synchronize :active_connection, :connection, :clear_active_connections!,
+ :clear_reloadable_connections!, :verify_active_connections!, :retrieve_connection,
+ :connected?, :disconnect!, :set_connection, :with => :@connection_mutex
+
private
def clear_cache!(cache, &block)
cache.each(&block) if block_given?
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
index e262b2bac5..ed9d074506 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -27,6 +27,8 @@ module ActiveRecord
@@connection_pools = {}
class << self
+ # Turning on allow_concurrency basically switches a null mutex for a real one, so that
+ # multi-threaded access of the connection pools hash is synchronized.
def allow_concurrency=(flag)
if @@allow_concurrency != flag
if flag
@@ -37,7 +39,7 @@ module ActiveRecord
end
end
- # for internal use only
+ # for internal use only and for testing
def active_connections #:nodoc:
@@connection_pools.inject({}) do |hash,kv|
hash[kv.first] = kv.last.active_connection
diff --git a/activesupport/lib/active_support/core_ext/module/synchronization.rb b/activesupport/lib/active_support/core_ext/module/synchronization.rb
index 7d54d496ab..6253594dfa 100644
--- a/activesupport/lib/active_support/core_ext/module/synchronization.rb
+++ b/activesupport/lib/active_support/core_ext/module/synchronization.rb
@@ -18,7 +18,7 @@ class Module
raise ArgumentError, "Synchronization needs a mutex. Supply an options hash with a :with key as the last argument (e.g. synchronize :hello, :with => :@mutex)."
end
- methods.each do |method|
+ methods.flatten.each do |method|
aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
if instance_methods.include?("#{aliased_method}_without_synchronization#{punctuation}")
raise ArgumentError, "#{method} is already synchronized. Double synchronization is not currently supported."
@@ -26,7 +26,7 @@ class Module
module_eval(<<-EOS, __FILE__, __LINE__)
def #{aliased_method}_with_synchronization#{punctuation}(*args, &block)
#{with}.synchronize do
- #{aliased_method}_without_synchronization#{punctuation}(*args,&block)
+ #{aliased_method}_without_synchronization#{punctuation}(*args, &block)
end
end
EOS