Module: Activerecord::Mysql::Reconnect
- Defined in:
- lib/activerecord/mysql/reconnect/version.rb,
lib/activerecord/mysql/reconnect.rb
Constant Summary collapse
- VERSION =
'0.3.5'- DEFAULT_EXECUTION_TRIES =
3- DEFAULT_EXECUTION_RETRY_WAIT =
0.5
- WITHOUT_RETRY_KEY =
'activerecord-mysql-reconnect-without-retry'- RETRYABLE_TRANSACTION_KEY =
'activerecord-mysql-reconnect-transaction-retry'- HANDLE_ERROR =
[ ActiveRecord::StatementInvalid, Mysql2::Error, ]
- HANDLE_R_ERROR_MESSAGES =
[ 'Lost connection to MySQL server during query', ]
- HANDLE_RW_ERROR_MESSAGES =
[ 'MySQL server has gone away', 'Server shutdown in progress', 'closed MySQL connection', "Can't connect to MySQL server", 'Query execution was interrupted', 'Access denied for user', 'The MySQL server is running with the --read-only option', "Can't connect to local MySQL server", # When running in local sandbox, or using a socket file 'Unknown MySQL server host', # For DNS blips ]
- HANDLE_ERROR_MESSAGES =
HANDLE_R_ERROR_MESSAGES + HANDLE_RW_ERROR_MESSAGES
- READ_SQL_REGEXP =
/\A\s*(?:SELECT|SHOW|SET)\b/i- RETRY_MODES =
[:r, :rw, :force]
- DEFAULT_RETRY_MODE =
:r
Class Method Summary collapse
- .enable_retry ⇒ Object
- .execution_retry_wait ⇒ Object
- .execution_tries ⇒ Object
- .logger ⇒ Object
- .retry_databases ⇒ Object
- .retry_databases=(v) ⇒ Object
- .retry_mode ⇒ Object
- .retry_mode=(v) ⇒ Object
- .retryable(opts) ⇒ Object
- .retryable_transaction ⇒ Object
- .retryable_transaction_buffer ⇒ Object
- .without_retry ⇒ Object
- .without_retry? ⇒ Boolean
Class Method Details
.enable_retry ⇒ Object
64 65 66 |
# File 'lib/activerecord/mysql/reconnect.rb', line 64 def enable_retry !!ActiveRecord::Base.enable_retry end |
.execution_retry_wait ⇒ Object
59 60 61 62 |
# File 'lib/activerecord/mysql/reconnect.rb', line 59 def execution_retry_wait wait = ActiveRecord::Base.execution_retry_wait || DEFAULT_EXECUTION_RETRY_WAIT wait.kind_of?(BigDecimal) ? wait : BigDecimal(wait.to_s) end |
.execution_tries ⇒ Object
55 56 57 |
# File 'lib/activerecord/mysql/reconnect.rb', line 55 def execution_tries ActiveRecord::Base.execution_tries || DEFAULT_EXECUTION_TRIES end |
.logger ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/activerecord/mysql/reconnect.rb', line 129 def logger if defined?(Rails) Rails.logger || ActiveRecord::Base.logger || Logger.new($stderr) else ActiveRecord::Base.logger || Logger.new($stderr) end end |
.retry_databases ⇒ Object
90 91 92 |
# File 'lib/activerecord/mysql/reconnect.rb', line 90 def retry_databases @activerecord_mysql_reconnect_retry_databases || [] end |
.retry_databases=(v) ⇒ Object
80 81 82 83 84 85 86 87 88 |
# File 'lib/activerecord/mysql/reconnect.rb', line 80 def retry_databases=(v) v ||= [] unless v.kind_of?(Array) v = [v] end @activerecord_mysql_reconnect_retry_databases = v.map {|i| i.to_s } end |
.retry_mode ⇒ Object
76 77 78 |
# File 'lib/activerecord/mysql/reconnect.rb', line 76 def retry_mode @activerecord_mysql_reconnect_retry_mode || DEFAULT_RETRY_MODE end |
.retry_mode=(v) ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/activerecord/mysql/reconnect.rb', line 68 def retry_mode=(v) unless RETRY_MODES.include?(v) raise "Invalid retry_mode. Please set one of the following: #{RETRY_MODES.map {|i| i.inspect }.join(', ')}" end @activerecord_mysql_reconnect_retry_mode = v end |
.retryable(opts) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/activerecord/mysql/reconnect.rb', line 94 def retryable(opts) block = opts.fetch(:proc) on_error = opts[:on_error] conn = opts[:connection] tries = self.execution_tries retval = nil retryable_loop(tries) do |n| begin retval = block.call break rescue => e if enable_retry and (tries.zero? or n < tries) and should_handle?(e, opts) on_error.call if on_error wait = self.execution_retry_wait * n opt_msgs = ["cause: #{e} [#{e.class}]"] if conn conn_info = connection_info(conn) opt_msgs << 'connection: ' + [:host, :database, :username].map {|k| "#{k}=#{conn_info[k]}" }.join(";") end logger.warn("MySQL server has gone away. Trying to reconnect in #{wait.to_f} seconds. (#{opt_msgs.join(', ')})") sleep(wait) next else raise e end end end return retval end |
.retryable_transaction ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/activerecord/mysql/reconnect.rb', line 150 def retryable_transaction begin Thread.current[RETRYABLE_TRANSACTION_KEY] = [] ActiveRecord::Base.transaction do yield end ensure Thread.current[RETRYABLE_TRANSACTION_KEY] = nil end end |
.retryable_transaction_buffer ⇒ Object
162 163 164 |
# File 'lib/activerecord/mysql/reconnect.rb', line 162 def retryable_transaction_buffer Thread.current[RETRYABLE_TRANSACTION_KEY] end |
.without_retry ⇒ Object
137 138 139 140 141 142 143 144 |
# File 'lib/activerecord/mysql/reconnect.rb', line 137 def without_retry begin Thread.current[WITHOUT_RETRY_KEY] = true yield ensure Thread.current[WITHOUT_RETRY_KEY] = nil end end |
.without_retry? ⇒ Boolean
146 147 148 |
# File 'lib/activerecord/mysql/reconnect.rb', line 146 def without_retry? !!Thread.current[WITHOUT_RETRY_KEY] end |