Module: Activerecord::Mysql::Reconnect
- Defined in:
- lib/activerecord/mysql/reconnect/version.rb,
lib/activerecord/mysql/reconnect.rb
Constant Summary collapse
- VERSION =
'0.3.3'- 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', ]
- 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_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
114 115 116 117 118 119 120 |
# File 'lib/activerecord/mysql/reconnect.rb', line 114 def logger if defined?(Rails) Rails.logger || ActiveRecord::Base.logger || Logger.new($stderr) else ActiveRecord::Base.logger || Logger.new($stderr) end 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
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/activerecord/mysql/reconnect.rb', line 80 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 and conn.kind_of?(Mysql2::Client) opt_msgs << 'connection: ' + [:host, :database, :username].map {|k| "#{k}=#{conn.query_options[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
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/activerecord/mysql/reconnect.rb', line 135 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
147 148 149 |
# File 'lib/activerecord/mysql/reconnect.rb', line 147 def retryable_transaction_buffer Thread.current[RETRYABLE_TRANSACTION_KEY] end |
.without_retry ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/activerecord/mysql/reconnect.rb', line 122 def without_retry begin Thread.current[WITHOUT_RETRY_KEY] = true yield ensure Thread.current[WITHOUT_RETRY_KEY] = nil end end |
.without_retry? ⇒ Boolean
131 132 133 |
# File 'lib/activerecord/mysql/reconnect.rb', line 131 def without_retry? !!Thread.current[WITHOUT_RETRY_KEY] end |