From 81c5242f43cb45d97b2a56409f8b39b0dba75ac3 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 19 Nov 2005 10:55:11 +0000 Subject: r3181@asus: jeremy | 2005-11-19 02:52:24 -0800 Mark connections for verification. Retrieve connection verifies before returning a connection. Verification tests whether the connection is marked then reconnects if the connection is inactive. All active connections are marked for verification after a request is handled. References #428. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3096 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/lib/active_record/base.rb | 6 +--- .../abstract/connection_specification.rb | 32 +++++++++++++++++++++ .../connection_adapters/abstract_adapter.rb | 33 ++++------------------ railties/lib/dispatcher.rb | 1 + 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 2f7812d17b..e79dd45d88 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -247,11 +247,7 @@ module ActiveRecord #:nodoc: # also be used to "borrow" the connection to do database work unrelated # to any of the specific Active Records. def self.connection - if allow_concurrency - retrieve_connection - else - @connection ||= retrieve_connection - end + retrieve_connection end # Returns the connection currently associated with the class. This can 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 a20304ea62..5e70930a85 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -1,4 +1,28 @@ module ActiveRecord + module ConnectionAdapters + module ConnectionManagement + # Check whether the connection should be checked for activity before use. + def needs_verification? + @needs_verification == true + end + + # Flag the connection for an activity check before use. + def needs_verification! + @needs_verification = true + end + + # If the connection is flagged for an activity check, check whether + # it is active and reconnect if not. + def verify! + if needs_verification? + reconnect! unless active? + @needs_verification = false + end + self + end + end + end + # The root class of all active record objects. class Base class ConnectionSpecification #:nodoc: @@ -78,8 +102,11 @@ module ActiveRecord ar_super = ActiveRecord::Base.superclass until klass == ar_super if conn = active_connections[klass] + # Validate the active connection before returning it. + conn.verify! return conn elsif conn = @@defined_connections[klass] + # Activate this connection specification. klass.connection = conn return self.connection end @@ -125,5 +152,10 @@ module ActiveRecord establish_connection spec end end + + # Mark active connections for verification on next retrieve_connection. + def self.mark_active_connections_for_verification! #:nodoc: + active_connections.values.each { |conn| conn.needs_verification! } + end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 096490ccef..bb6202666e 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -19,15 +19,9 @@ module ActiveRecord # SchemaStatements#add_column, SchemaStatements#change_column and # SchemaStatements#remove_column are very useful. class AbstractAdapter - include Quoting, DatabaseStatements, SchemaStatements + include Quoting, DatabaseStatements, SchemaStatements, ConnectionManagement @@row_even = true - @@reconnect_success = 0 - @@reconnect_failure = 0 - def self.reconnect_success_rate - (100.0 * @@reconnect_success / (@@reconnect_success + @@reconnect_failure)).to_i - end - def initialize(connection, logger = nil) #:nodoc: @connection, @logger = connection, logger @runtime = 0 @@ -75,10 +69,11 @@ module ActiveRecord nil end rescue Exception => e + # Flag connection as possibly dirty; needs verification before use. + self.needs_verification! + + # Log message and raise exception. message = "#{e.class.name}: #{e.message}: #{sql}" - unless reconnect_if_inactive! - message = "(reconnect failed) #{message}" - end log_info(message, name, 0) raise ActiveRecord::StatementInvalid, message end @@ -111,24 +106,6 @@ module ActiveRecord "%s %s" % [message, dump] end end - - private - def reconnect_if_inactive! - if respond_to?(:active?) and respond_to?(:reconnect!) - reconnect! unless active? - if active? - @@reconnect_success += 1 - @logger.info "#{adapter_name} automatically reconnected. Success rate: #{self.class.reconnect_success_rate}%" if @logger - true - else - @@reconnect_failure += 1 - @logger.warn "#{adapter_name} automatic reconnection failed. Success rate: #{self.class.reconnect_success_rate}%" if @logger - false - end - else - @logger.warn "#{adapter_name} does not yet support automatic reconnection." if @logger - end - end end end end diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb index a2fc6e8553..e155421cc6 100644 --- a/railties/lib/dispatcher.rb +++ b/railties/lib/dispatcher.rb @@ -73,6 +73,7 @@ class Dispatcher def reset_after_dispatch reset_application! if Dependencies.load? + ActiveRecord::Base.mark_active_connections_for_verification! Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT) end -- cgit v1.2.3