Module: Activerecord::Mysql::Reconnect
- Defined in:
- lib/activerecord/mysql/reconnect/version.rb,
lib/activerecord/mysql/reconnect.rb
Constant Summary collapse
- VERSION =
'0.3.6'
- 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 "Lost connection to MySQL server at 'reading initial communication packet'", ]
- 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
65 66 67 |
# File 'lib/activerecord/mysql/reconnect.rb', line 65 def enable_retry !!ActiveRecord::Base.enable_retry end |
.execution_retry_wait ⇒ Object
60 61 62 63 |
# File 'lib/activerecord/mysql/reconnect.rb', line 60 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
56 57 58 |
# File 'lib/activerecord/mysql/reconnect.rb', line 56 def execution_tries ActiveRecord::Base.execution_tries || DEFAULT_EXECUTION_TRIES end |
.logger ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/activerecord/mysql/reconnect.rb', line 130 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
91 92 93 |
# File 'lib/activerecord/mysql/reconnect.rb', line 91 def retry_databases @activerecord_mysql_reconnect_retry_databases || [] end |
.retry_databases=(v) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/activerecord/mysql/reconnect.rb', line 81 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
77 78 79 |
# File 'lib/activerecord/mysql/reconnect.rb', line 77 def retry_mode @activerecord_mysql_reconnect_retry_mode || DEFAULT_RETRY_MODE end |
.retry_mode=(v) ⇒ Object
69 70 71 72 73 74 75 |
# File 'lib/activerecord/mysql/reconnect.rb', line 69 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
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 128 |
# File 'lib/activerecord/mysql/reconnect.rb', line 95 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
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/activerecord/mysql/reconnect.rb', line 151 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
163 164 165 |
# File 'lib/activerecord/mysql/reconnect.rb', line 163 def retryable_transaction_buffer Thread.current[RETRYABLE_TRANSACTION_KEY] end |
.without_retry ⇒ Object
138 139 140 141 142 143 144 145 |
# File 'lib/activerecord/mysql/reconnect.rb', line 138 def without_retry begin Thread.current[WITHOUT_RETRY_KEY] = true yield ensure Thread.current[WITHOUT_RETRY_KEY] = nil end end |
.without_retry? ⇒ Boolean
147 148 149 |
# File 'lib/activerecord/mysql/reconnect.rb', line 147 def without_retry? !!Thread.current[WITHOUT_RETRY_KEY] end |