diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-16 14:33:12 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-16 14:33:38 -0800 |
commit | aaff1a4101605b7d2e2386d3e7612a43fbe07c8d (patch) | |
tree | 979f9828edaa35a7a5e33727d4f3856a6b95a45c /activerecord/lib/active_record | |
parent | c84e4b5d4bf0eefea9f0f649da6b82ec636678c2 (diff) | |
download | rails-aaff1a4101605b7d2e2386d3e7612a43fbe07c8d.tar.gz rails-aaff1a4101605b7d2e2386d3e7612a43fbe07c8d.tar.bz2 rails-aaff1a4101605b7d2e2386d3e7612a43fbe07c8d.zip |
database connections are automatically established after forking.
Connection pools are 1:1 with pids.
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb | 60 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 6 |
2 files changed, 52 insertions, 14 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 d69f02d504..7cbf01ec65 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -328,16 +328,18 @@ module ActiveRecord # ActiveRecord::Base.connection_handler. Active Record models use this to # determine that connection pool that they should use. class ConnectionHandler - attr_reader :connection_pools - - def initialize(pools = {}) + def initialize(pools = Hash.new { |h,k| h[k] = {} }) @connection_pools = pools - @class_to_pool = {} + @class_to_pool = Hash.new { |h,k| h[k] = {} } + end + + def connection_pools + @connection_pools[$$] end def establish_connection(name, spec) - @connection_pools[spec] ||= ConnectionAdapters::ConnectionPool.new(spec) - @class_to_pool[name] = @connection_pools[spec] + set_pool_for_spec spec, ConnectionAdapters::ConnectionPool.new(spec) + set_class_to_pool name, connection_pools[spec] end # Returns true if there are any active connections among the connection @@ -350,21 +352,21 @@ module ActiveRecord # and also returns connections to the pool cached by threads that are no # longer alive. def clear_active_connections! - @connection_pools.each_value {|pool| pool.release_connection } + connection_pools.each_value {|pool| pool.release_connection } end # Clears the cache which maps classes. def clear_reloadable_connections! - @connection_pools.each_value {|pool| pool.clear_reloadable_connections! } + connection_pools.each_value {|pool| pool.clear_reloadable_connections! } end def clear_all_connections! - @connection_pools.each_value {|pool| pool.disconnect! } + connection_pools.each_value {|pool| pool.disconnect! } end # Verify active connections. def verify_active_connections! #:nodoc: - @connection_pools.each_value {|pool| pool.verify_active_connections! } + connection_pools.each_value {|pool| pool.verify_active_connections! } end # Locate the connection of the nearest super class. This can be an @@ -388,21 +390,53 @@ module ActiveRecord # can be used as an argument for establish_connection, for easily # re-establishing the connection. def remove_connection(klass) - pool = @class_to_pool.delete(klass.name) + pool = class_to_pool.delete(klass.name) return nil unless pool - @connection_pools.delete pool.spec + connection_pools.delete pool.spec pool.automatic_reconnect = false pool.disconnect! pool.spec.config end def retrieve_connection_pool(klass) - pool = @class_to_pool[klass.name] + pool = get_pool_for_class klass.name return pool if pool return nil if ActiveRecord::Model == klass retrieve_connection_pool klass.active_record_super end + + private + + def class_to_pool + @class_to_pool[$$] + end + + def set_pool_for_spec(spec, pool) + @connection_pools[$$][spec] = pool + end + + def set_class_to_pool(name, pool) + @class_to_pool[$$][name] = pool + pool + end + + def get_pool_for_class(klass) + @class_to_pool[$$].fetch(klass) { + c_to_p = @class_to_pool.values.find { |class_to_pool| + class_to_pool[klass] + } + + if c_to_p + pool = c_to_p[klass] + pool = ConnectionAdapters::ConnectionPool.new pool.spec + set_pool_for_spec pool.spec, pool + set_class_to_pool klass, pool + else + set_class_to_pool klass, nil + end + } + end end class ConnectionManagement diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index fd5cbd3f9a..7414d38aea 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -1238,7 +1238,11 @@ module ActiveRecord # prepared statements whose return value may have changed is # FEATURE_NOT_SUPPORTED. Check here for more details: # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573 - code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE) + begin + code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE) + rescue + raise e + end if FEATURE_NOT_SUPPORTED == code @statements.delete sql_key(sql) retry |