mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
r3042@asus: jeremy | 2005-11-13 01:51:08 -0800
MySQL active? and reconnect! References #428. r3043@asus: jeremy | 2005-11-13 01:58:28 -0800 SQLite active? and reconnect! References #428. r3044@asus: jeremy | 2005-11-13 02:02:27 -0800 Update CHANGELOG with admonishment regarding avoidance of the log method. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3001 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
44b64704dd
commit
680e4742be
4 changed files with 52 additions and 20 deletions
|
@ -1,6 +1,6 @@
|
|||
*SVN*
|
||||
|
||||
* When AbstractAdapter#log rescues an exception, attempt to detect and reconnect to an inactive database connection. Connection adapter must respond to the active? and reconnect! instance methods. Initial support for PostgreSQL. [Jeremy Kemper]
|
||||
* When AbstractAdapter#log rescues an exception, attempt to detect and reconnect to an inactive database connection. Connection adapter must respond to the active? and reconnect! instance methods. Initial support for PostgreSQL, MySQL, and SQLite. Make certain that all statements which may need reconnection are performed within a logged block: for example, this means no avoiding log(sql, name) { } if @logger.nil? [Jeremy Kemper]
|
||||
|
||||
* Much faster Oracle column reflection. #2848 [Michael Schoen <schoenm@earthlink.net>]
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@ module ActiveRecord
|
|||
include Quoting, DatabaseStatements, SchemaStatements
|
||||
@@row_even = true
|
||||
|
||||
@@reconnect_success = 0
|
||||
@@reconnect_failure = 0
|
||||
def self.reconnect_success_rate
|
||||
@@reconnect_success.to_f / (@@reconnect_success + @@reconnect_failure)
|
||||
end
|
||||
|
||||
def initialize(connection, logger = nil) #:nodoc:
|
||||
@connection, @logger = connection, logger
|
||||
@runtime = 0
|
||||
|
@ -40,9 +46,8 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def reset_runtime #:nodoc:
|
||||
rt = @runtime
|
||||
@runtime = 0
|
||||
return rt
|
||||
rt, @runtime = @runtime, 0
|
||||
rt
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -100,7 +105,14 @@ module ActiveRecord
|
|||
def reconnect_if_inactive!
|
||||
if respond_to?(:active?) and respond_to?(:reconnect!)
|
||||
reconnect! unless active?
|
||||
raise ActiveRecord::ConnectionFailed unless active?
|
||||
if active?
|
||||
@@reconnect_success += 1
|
||||
@logger.info "#{adapter_name} automatically reconnected. Success rate: #{'%.2f' % self.class.reconnect_success_rate}%" if @logger
|
||||
else
|
||||
@@reconnect_failure += 1
|
||||
@logger.warn "#{adapter_name} automatic reconnection failed. Success rate: #{'%.2f' % self.class.reconnect_success_rate}%" if @logger
|
||||
raise ActiveRecord::ConnectionFailed
|
||||
end
|
||||
else
|
||||
@logger.warn "#{adapter_name} does not yet support automatic reconnection." if @logger
|
||||
end
|
||||
|
|
|
@ -136,6 +136,25 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
|
||||
# CONNECTION MANAGEMENT ====================================
|
||||
|
||||
def active?
|
||||
@connection.stat if @connection.respond_to?(:stat)
|
||||
true
|
||||
rescue Mysql::Error
|
||||
false
|
||||
end
|
||||
|
||||
def reconnect!
|
||||
if @connection.respond_to?(:ping)
|
||||
@connection.ping
|
||||
else
|
||||
@connection.close rescue nil
|
||||
@connection.real_connect(*@connection_options)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# DATABASE STATEMENTS ======================================
|
||||
|
||||
def select_all(sql, name = nil) #:nodoc:
|
||||
|
@ -148,22 +167,10 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def execute(sql, name = nil, retries = 2) #:nodoc:
|
||||
unless @logger
|
||||
@connection.query(sql)
|
||||
else
|
||||
log(sql, name) { @connection.query(sql) }
|
||||
end
|
||||
log(sql, name) { @connection.query(sql) }
|
||||
rescue ActiveRecord::StatementInvalid => exception
|
||||
if LOST_CONNECTION_ERROR_MESSAGES.any? { |msg| exception.message.split(":").first =~ /^#{msg}/ }
|
||||
@connection.real_connect(*@connection_options)
|
||||
unless @logger
|
||||
@connection.query(sql)
|
||||
else
|
||||
@logger.info "Retrying invalid statement with reopened connection"
|
||||
log(sql, name) { @connection.query(sql) }
|
||||
end
|
||||
elsif exception.message.split(":").first =~ /Packets out of order/
|
||||
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem update mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information."
|
||||
if exception.message.split(":").first =~ /Packets out of order/
|
||||
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
|
||||
else
|
||||
raise
|
||||
end
|
||||
|
|
|
@ -127,6 +127,19 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
|
||||
# CONNECTION MANAGEMENT ====================================
|
||||
|
||||
def active?
|
||||
# TODO: SQLite is an embedded db, it doesn't lose connections,
|
||||
# but perhaps some of its exceptions merit a retry, such as
|
||||
# LockedException.
|
||||
true
|
||||
end
|
||||
|
||||
def reconnect!
|
||||
end
|
||||
|
||||
|
||||
# DATABASE STATEMENTS ======================================
|
||||
|
||||
def execute(sql, name = nil) #:nodoc:
|
||||
|
|
Loading…
Reference in a new issue