Module: Activerecord::Mysql::Reconnect
- Defined in:
- lib/activerecord/mysql/reconnect/version.rb,
lib/activerecord/mysql/reconnect.rb
Constant Summary collapse
- VERSION =
'0.3.1'- 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', ]
- 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
61 62 63 |
# File 'lib/activerecord/mysql/reconnect.rb', line 61 def enable_retry !!ActiveRecord::Base.enable_retry end |
.execution_retry_wait ⇒ Object
57 58 59 |
# File 'lib/activerecord/mysql/reconnect.rb', line 57 def execution_retry_wait ActiveRecord::Base.execution_retry_wait || DEFAULT_EXECUTION_RETRY_WAIT end |
.execution_tries ⇒ Object
53 54 55 |
# File 'lib/activerecord/mysql/reconnect.rb', line 53 def execution_tries ActiveRecord::Base.execution_tries || DEFAULT_EXECUTION_TRIES end |
.logger ⇒ Object
111 112 113 114 115 116 117 |
# File 'lib/activerecord/mysql/reconnect.rb', line 111 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
73 74 75 |
# File 'lib/activerecord/mysql/reconnect.rb', line 73 def retry_mode @activerecord_mysql_reconnect_retry_mode || DEFAULT_RETRY_MODE end |
.retry_mode=(v) ⇒ Object
65 66 67 68 69 70 71 |
# File 'lib/activerecord/mysql/reconnect.rb', line 65 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
77 78 79 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 |
# File 'lib/activerecord/mysql/reconnect.rb', line 77 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} seconds. (#{opt_msgs.join(', ')})") sleep(wait) next else raise e end end end return retval end |
.retryable_transaction ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/activerecord/mysql/reconnect.rb', line 132 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
144 145 146 |
# File 'lib/activerecord/mysql/reconnect.rb', line 144 def retryable_transaction_buffer Thread.current[RETRYABLE_TRANSACTION_KEY] end |
.without_retry ⇒ Object
119 120 121 122 123 124 125 126 |
# File 'lib/activerecord/mysql/reconnect.rb', line 119 def without_retry begin Thread.current[WITHOUT_RETRY_KEY] = true yield ensure Thread.current[WITHOUT_RETRY_KEY] = nil end end |
.without_retry? ⇒ Boolean
128 129 130 |
# File 'lib/activerecord/mysql/reconnect.rb', line 128 def without_retry? !!Thread.current[WITHOUT_RETRY_KEY] end |