activerecord-mysql-reconnect 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/ChangeLog +12 -0
- data/README.md +2 -1
- data/lib/activerecord/mysql/reconnect.rb +52 -13
- data/lib/activerecord/mysql/reconnect/abstract_mysql_adapter_ext.rb +4 -1
- data/lib/activerecord/mysql/reconnect/base_ext.rb +4 -3
- data/lib/activerecord/mysql/reconnect/mysql2_adapter_ext.rb +2 -1
- data/lib/activerecord/mysql/reconnect/version.rb +1 -1
- data/spec/activerecord-mysql-reconnect_spec.rb +128 -106
- data/spec/spec_helper.rb +56 -3
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDdmZDFhNjRlZDc1YWRhY2I0NmFhZTViZDA4MjEzN2RkMTJlMTRiZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZWEwZGEwNGNmYTExNjA5MmRkYjcxOWZjYjMxMjk0ZjBjYTI3NzJhYw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTE2ZTU2OTMxNTk4MzYyY2FiMzdlZWFhMDBlMjE1ZDlhMDBmYjk4OTQyN2Ji
|
10
|
+
MDc1YzhmNjQ4ZGU5MWJmMWNlZDYzZTNlMTRjNTgwMjNmZTJmY2RhMDQxMzRi
|
11
|
+
ODhjYmM1NmIyZTZmNGQzY2QyZDEyYzY3NjE2YmI5NmM4YTI5MzU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzNhOTRmMTZiZTU0MmM4NTdiM2FkMDI2Y2QzZDkyMTA3ZTgwOGM4MjM5ZGY3
|
14
|
+
YjcwZGUxNDE0ODE4MDkxNzM3Yzg2MWNmMmZjNDBmYWI0NTYyZDAzYmI1NjI2
|
15
|
+
ZGI4YzIwZTZiNWU3Y2VmYjljNmIxMzhlYjJlYzlkNDg5NjRlYTM=
|
data/ChangeLog
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
activerecord-mysql-reconnect 0.3.0 (January 9, 2014)
|
2
|
+
|
3
|
+
* Retry is disabled by default
|
4
|
+
* Read-only mode is added
|
5
|
+
|
6
|
+
activerecord-mysql-reconnect 0.2.0 (January 4, 2014)
|
7
|
+
|
8
|
+
* Retry transaction is supported
|
9
|
+
|
10
|
+
activerecord-mysql-reconnect 0.1.0 (October 11, 2013)
|
11
|
+
|
12
|
+
* activerecord-mysql-reconnect is released
|
data/README.md
CHANGED
@@ -91,6 +91,7 @@ MyApp::Application.configure do
|
|
91
91
|
config.active_record.enable_retry = true
|
92
92
|
config.active_record.execution_tries = 10 # times
|
93
93
|
config.active_record.execution_retry_wait = 1.5 # sec
|
94
|
+
config.active_record.retry_read_only = false # default: true
|
94
95
|
...
|
95
96
|
ene
|
96
97
|
```
|
@@ -101,7 +102,7 @@ ene
|
|
101
102
|
mysql.server start
|
102
103
|
export ACTIVERECORD_MYSQL_RECONNECT_MYSQL_START='mysql.server start'
|
103
104
|
export ACTIVERECORD_MYSQL_RECONNECT_MYSQL_STOP='mysql.server stop'
|
104
|
-
export ACTIVERECORD_MYSQL_RECONNECT_MYSQL_RESTART='mysql.server restart'
|
105
|
+
export ACTIVERECORD_MYSQL_RECONNECT_MYSQL_RESTART='killall -9 mysqld; sleep 3; mysql.server restart; true'
|
105
106
|
bundle install
|
106
107
|
bundle exec rake
|
107
108
|
```
|
@@ -11,7 +11,8 @@ require 'active_support'
|
|
11
11
|
|
12
12
|
require 'activerecord/mysql/reconnect/version'
|
13
13
|
require 'activerecord/mysql/reconnect/base_ext'
|
14
|
-
|
14
|
+
# XXX:
|
15
|
+
#require 'activerecord/mysql/reconnect/abstract_adapter_ext'
|
15
16
|
require 'activerecord/mysql/reconnect/abstract_mysql_adapter_ext'
|
16
17
|
require 'activerecord/mysql/reconnect/mysql2_adapter_ext'
|
17
18
|
require 'activerecord/mysql/reconnect/connection_pool_ext'
|
@@ -28,16 +29,23 @@ module Activerecord::Mysql::Reconnect
|
|
28
29
|
Mysql2::Error,
|
29
30
|
]
|
30
31
|
|
31
|
-
|
32
|
+
HANDLE_R_ERROR_MESSAGES = [
|
33
|
+
'Lost connection to MySQL server during query',
|
34
|
+
]
|
35
|
+
|
36
|
+
HANDLE_RW_ERROR_MESSAGES = [
|
32
37
|
'MySQL server has gone away',
|
33
38
|
'Server shutdown in progress',
|
34
39
|
'closed MySQL connection',
|
35
40
|
"Can't connect to MySQL server",
|
36
41
|
'Query execution was interrupted',
|
37
42
|
'Access denied for user',
|
38
|
-
'Lost connection to MySQL server during query',
|
39
43
|
]
|
40
44
|
|
45
|
+
HANDLE_ERROR_MESSAGES = HANDLE_R_ERROR_MESSAGES + HANDLE_RW_ERROR_MESSAGES
|
46
|
+
|
47
|
+
READ_SQL_REGEXP = /\A\s*(?:SELECT|SHOW|SET)\b/i
|
48
|
+
|
41
49
|
class << self
|
42
50
|
def execution_tries
|
43
51
|
ActiveRecord::Base.execution_tries || DEFAULT_EXECUTION_TRIES
|
@@ -51,21 +59,33 @@ module Activerecord::Mysql::Reconnect
|
|
51
59
|
!!ActiveRecord::Base.enable_retry
|
52
60
|
end
|
53
61
|
|
62
|
+
def retry_read_only
|
63
|
+
!!ActiveRecord::Base.retry_read_only
|
64
|
+
end
|
65
|
+
|
54
66
|
def retryable(opts)
|
55
|
-
block
|
56
|
-
on_error
|
57
|
-
|
58
|
-
|
67
|
+
block = opts.fetch(:proc)
|
68
|
+
on_error = opts[:on_error]
|
69
|
+
conn = opts[:connection]
|
70
|
+
tries = self.execution_tries
|
71
|
+
retval = nil
|
59
72
|
|
60
73
|
retryable_loop(tries) do |n|
|
61
74
|
begin
|
62
75
|
retval = block.call
|
63
76
|
break
|
64
77
|
rescue => e
|
65
|
-
if enable_retry and (tries.zero? or n < tries) and should_handle?(e)
|
78
|
+
if enable_retry and (tries.zero? or n < tries) and should_handle?(e, opts)
|
66
79
|
on_error.call if on_error
|
67
80
|
wait = self.execution_retry_wait * n
|
68
|
-
|
81
|
+
|
82
|
+
opt_msgs = ["cause: #{e} [#{e.class}]"]
|
83
|
+
|
84
|
+
if conn and conn.kind_of?(Mysql2::Client)
|
85
|
+
opt_msgs << 'connection: ' + [:host, :database, :username].map {|k| "#{k}=#{conn.query_options[k]}" }.join(";")
|
86
|
+
end
|
87
|
+
|
88
|
+
logger.warn("MySQL server has gone away. Trying to reconnect in #{wait} seconds. (#{opt_msgs.join(', ')})")
|
69
89
|
sleep(wait)
|
70
90
|
next
|
71
91
|
else
|
@@ -124,10 +144,29 @@ module Activerecord::Mysql::Reconnect
|
|
124
144
|
end
|
125
145
|
end
|
126
146
|
|
127
|
-
def should_handle?(e)
|
128
|
-
|
129
|
-
|
130
|
-
|
147
|
+
def should_handle?(e, opts = {})
|
148
|
+
sql = opts[:sql]
|
149
|
+
read_only = opts[:read_only]
|
150
|
+
|
151
|
+
if without_retry?
|
152
|
+
return false
|
153
|
+
end
|
154
|
+
|
155
|
+
unless HANDLE_ERROR.any? {|i| e.kind_of?(i) }
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
|
159
|
+
unless Regexp.union(HANDLE_ERROR_MESSAGES) =~ e.message
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
|
163
|
+
if sql and READ_SQL_REGEXP !~ sql
|
164
|
+
if read_only or Regexp.union(HANDLE_R_ERROR_MESSAGES) =~ e.message
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
return true
|
131
170
|
end
|
132
171
|
end # end of class methods
|
133
172
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class ActiveRecord::Base
|
2
|
-
class_attribute :execution_tries,
|
3
|
-
class_attribute :execution_retry_wait, :
|
4
|
-
class_attribute :enable_retry,
|
2
|
+
class_attribute :execution_tries, :instance_accessor => false
|
3
|
+
class_attribute :execution_retry_wait, :instance_accessor => false
|
4
|
+
class_attribute :enable_retry, :instance_accessor => false
|
5
|
+
class_attribute :retry_read_only, :instance_accessor => false, :default => true
|
5
6
|
|
6
7
|
class << self
|
7
8
|
def without_retry
|
@@ -17,17 +17,10 @@ describe 'activerecord-mysql-reconnect' do
|
|
17
17
|
|
18
18
|
it 'on select' do
|
19
19
|
expect {
|
20
|
-
|
21
|
-
|
22
|
-
th = Thread.start {
|
23
|
-
thread_running = true
|
24
|
-
expect(Employee.where(:id => 1).pluck('sleep(15)')).to eq([1])
|
25
|
-
thread_running = false
|
20
|
+
th = thread_run {|do_stop|
|
21
|
+
expect(Employee.where(:id => 1).pluck('sleep(15) * 0')).to eq([0])
|
26
22
|
}
|
27
23
|
|
28
|
-
th.abort_on_exception = true
|
29
|
-
sleep 3
|
30
|
-
expect(thread_running).to be_true
|
31
24
|
mysql_restart
|
32
25
|
expect(Employee.count).to be >= 300024
|
33
26
|
th.join
|
@@ -36,25 +29,25 @@ describe 'activerecord-mysql-reconnect' do
|
|
36
29
|
|
37
30
|
it 'on insert' do
|
38
31
|
expect {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
32
|
+
th = thread_run {|do_stop|
|
33
|
+
emp = nil
|
34
|
+
|
35
|
+
mysql2_error('MySQL server has gone away') do
|
36
|
+
emp = Employee.create(
|
37
|
+
:emp_no => 1,
|
38
|
+
:birth_date => Time.now,
|
39
|
+
:first_name => "' + sleep(15) + '",
|
40
|
+
:last_name => 'Tiger',
|
41
|
+
:hire_date => Time.now
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
do_stop.call
|
46
|
+
|
51
47
|
expect(emp.id).to eq(300025)
|
52
48
|
expect(emp.emp_no).to eq(1)
|
53
49
|
}
|
54
50
|
|
55
|
-
th.abort_on_exception = true
|
56
|
-
sleep 3
|
57
|
-
expect(thread_running).to be_true
|
58
51
|
mysql_restart
|
59
52
|
expect(Employee.count).to be >= 300024
|
60
53
|
th.join
|
@@ -63,23 +56,21 @@ describe 'activerecord-mysql-reconnect' do
|
|
63
56
|
|
64
57
|
it 'op update' do
|
65
58
|
expect {
|
66
|
-
|
67
|
-
|
68
|
-
th = Thread.start {
|
69
|
-
thread_running = true
|
59
|
+
th = thread_run {|do_stop|
|
70
60
|
emp = Employee.where(:id => 1).first
|
71
61
|
emp.first_name = "' + sleep(15) + '"
|
72
62
|
emp.last_name = 'ZapZapZap'
|
73
|
-
|
74
|
-
|
63
|
+
|
64
|
+
mysql2_error('MySQL server has gone away') do
|
65
|
+
emp.save!
|
66
|
+
end
|
67
|
+
|
68
|
+
do_stop.call
|
75
69
|
|
76
70
|
emp = Employee.where(:id => 1).first
|
77
71
|
expect(emp.last_name).to eq('ZapZapZap')
|
78
72
|
}
|
79
73
|
|
80
|
-
th.abort_on_exception = true
|
81
|
-
sleep 3
|
82
|
-
expect(thread_running).to be_true
|
83
74
|
mysql_restart
|
84
75
|
expect(Employee.count).to eq(300024)
|
85
76
|
th.join
|
@@ -100,26 +91,28 @@ describe 'activerecord-mysql-reconnect' do
|
|
100
91
|
expect {
|
101
92
|
expect(Employee.count).to eq(300024)
|
102
93
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
94
|
+
mysql2_error('MySQL server has gone away') do
|
95
|
+
ActiveRecord::Base.transaction do
|
96
|
+
emp = Employee.create(
|
97
|
+
:emp_no => 1,
|
98
|
+
:birth_date => Time.now,
|
99
|
+
:first_name => 'Scott',
|
100
|
+
:last_name => 'Tiger',
|
101
|
+
:hire_date => Time.now
|
102
|
+
)
|
103
|
+
expect(emp.id).to eq(300025)
|
104
|
+
expect(emp.emp_no).to eq(1)
|
105
|
+
mysql_restart
|
106
|
+
emp = Employee.create(
|
107
|
+
:emp_no => 2,
|
108
|
+
:birth_date => Time.now,
|
109
|
+
:first_name => 'Scott',
|
110
|
+
:last_name => 'Tiger',
|
111
|
+
:hire_date => Time.now
|
112
|
+
)
|
113
|
+
expect(emp.id).to eq(300025)
|
114
|
+
expect(emp.emp_no).to eq(2)
|
115
|
+
end
|
123
116
|
end
|
124
117
|
|
125
118
|
expect(Employee.count).to eq(300025)
|
@@ -130,36 +123,38 @@ describe 'activerecord-mysql-reconnect' do
|
|
130
123
|
expect {
|
131
124
|
expect(Employee.count).to eq(300024)
|
132
125
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
126
|
+
mysql2_error('MySQL server has gone away') do
|
127
|
+
ActiveRecord::Base.retryable_transaction do
|
128
|
+
emp = Employee.create(
|
129
|
+
:emp_no => 1,
|
130
|
+
:birth_date => Time.now,
|
131
|
+
:first_name => 'Scott',
|
132
|
+
:last_name => 'Tiger',
|
133
|
+
:hire_date => Time.now
|
134
|
+
)
|
135
|
+
expect(emp.id).to eq(300025)
|
136
|
+
expect(emp.emp_no).to eq(1)
|
137
|
+
mysql_restart
|
138
|
+
emp = Employee.create(
|
139
|
+
:emp_no => 2,
|
140
|
+
:birth_date => Time.now,
|
141
|
+
:first_name => 'Scott',
|
142
|
+
:last_name => 'Tiger',
|
143
|
+
:hire_date => Time.now
|
144
|
+
)
|
145
|
+
expect(emp.id).to eq(300026)
|
146
|
+
expect(emp.emp_no).to eq(2)
|
147
|
+
mysql_restart
|
148
|
+
emp = Employee.create(
|
149
|
+
:emp_no => 3,
|
150
|
+
:birth_date => Time.now,
|
151
|
+
:first_name => 'Scott',
|
152
|
+
:last_name => 'Tiger',
|
153
|
+
:hire_date => Time.now
|
154
|
+
)
|
155
|
+
expect(emp.id).to eq(300027)
|
156
|
+
expect(emp.emp_no).to eq(3)
|
157
|
+
end
|
163
158
|
end
|
164
159
|
|
165
160
|
expect(Employee.count).to eq(300027)
|
@@ -176,19 +171,12 @@ describe 'activerecord-mysql-reconnect' do
|
|
176
171
|
|
177
172
|
it 'retry verify' do
|
178
173
|
expect {
|
179
|
-
|
180
|
-
|
181
|
-
th = Thread.start {
|
182
|
-
thread_running = true
|
174
|
+
th = thread_run {|do_stop|
|
183
175
|
mysql_stop
|
184
176
|
sleep 15
|
185
177
|
mysql_start
|
186
|
-
thread_running = false
|
187
178
|
}
|
188
179
|
|
189
|
-
th.abort_on_exception = true
|
190
|
-
sleep 3
|
191
|
-
expect(thread_running).to be_true
|
192
180
|
ActiveRecord::Base.connection.verify!
|
193
181
|
th.join
|
194
182
|
}.to_not raise_error
|
@@ -196,35 +184,25 @@ describe 'activerecord-mysql-reconnect' do
|
|
196
184
|
|
197
185
|
it 'retry reconnect' do
|
198
186
|
expect {
|
199
|
-
|
200
|
-
|
201
|
-
th = Thread.start {
|
202
|
-
thread_running = true
|
187
|
+
th = thread_run {|do_stop|
|
203
188
|
mysql_stop
|
204
189
|
sleep 15
|
205
190
|
mysql_start
|
206
|
-
thread_running = false
|
207
191
|
}
|
208
192
|
|
209
|
-
th.abort_on_exception = true
|
210
|
-
sleep 3
|
211
|
-
expect(thread_running).to be_true
|
212
193
|
ActiveRecord::Base.connection.reconnect!
|
213
194
|
th.join
|
214
195
|
}.to_not raise_error
|
215
196
|
end
|
216
197
|
|
217
198
|
it 'disable reconnect' do
|
218
|
-
|
219
|
-
|
220
|
-
ActiveRecord::Base.enable_retry = false
|
199
|
+
disable_retry do
|
200
|
+
expect {
|
221
201
|
expect(Employee.all.length).to eq(300024)
|
222
202
|
mysql_restart
|
223
203
|
expect(Employee.all.length).to eq(300024)
|
224
|
-
|
225
|
-
|
226
|
-
end
|
227
|
-
}.to raise_error(ActiveRecord::StatementInvalid)
|
204
|
+
}.to raise_error(ActiveRecord::StatementInvalid)
|
205
|
+
end
|
228
206
|
|
229
207
|
expect {
|
230
208
|
expect(Employee.all.length).to eq(300024)
|
@@ -232,4 +210,48 @@ describe 'activerecord-mysql-reconnect' do
|
|
232
210
|
expect(Employee.all.length).to eq(300024)
|
233
211
|
}.to_not raise_error
|
234
212
|
end
|
213
|
+
|
214
|
+
it 'read only (read)' do
|
215
|
+
enable_read_only do
|
216
|
+
expect {
|
217
|
+
expect(Employee.all.length).to eq(300024)
|
218
|
+
mysql_restart
|
219
|
+
expect(Employee.all.length).to eq(300024)
|
220
|
+
}.to_not raise_error
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'read only (write)' do
|
225
|
+
enable_read_only do
|
226
|
+
expect {
|
227
|
+
th = thread_run {|do_stop|
|
228
|
+
mysql2_error('MySQL server has gone away') do
|
229
|
+
emp = Employee.create(
|
230
|
+
:emp_no => 1,
|
231
|
+
:birth_date => Time.now,
|
232
|
+
:first_name => "' + sleep(15) + '",
|
233
|
+
:last_name => 'Tiger',
|
234
|
+
:hire_date => Time.now
|
235
|
+
)
|
236
|
+
end
|
237
|
+
}
|
238
|
+
|
239
|
+
mysql_restart
|
240
|
+
th.join
|
241
|
+
}.to raise_error(ActiveRecord::StatementInvalid)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'lost connection' do
|
246
|
+
mysql2_error('Lost connection to MySQL server during query') do
|
247
|
+
expect {
|
248
|
+
th = thread_run {|do_stop|
|
249
|
+
ActiveRecord::Base.connection.execute("INTO `employees` (`birth_date`, `emp_no`, `first_name`, `hire_date`, `last_name`) VALUES ('2014-01-09 03:22:25', 1, '' + sleep(15) + '', '2014-01-09 03:22:25', 'Tiger')")
|
250
|
+
}
|
251
|
+
|
252
|
+
mysql_restart
|
253
|
+
th.join
|
254
|
+
}.to raise_error(ActiveRecord::StatementInvalid)
|
255
|
+
end
|
256
|
+
end
|
235
257
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,17 +4,17 @@ require 'mysql2'
|
|
4
4
|
class Employee < ActiveRecord::Base; end
|
5
5
|
|
6
6
|
def mysql_start
|
7
|
-
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_START'] || 'sudo
|
7
|
+
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_START'] || 'sudo service mysql start'
|
8
8
|
system(cmd)
|
9
9
|
end
|
10
10
|
|
11
11
|
def mysql_stop
|
12
|
-
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_STOP'] || 'sudo
|
12
|
+
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_STOP'] || 'sudo service mysql stop'
|
13
13
|
system(cmd)
|
14
14
|
end
|
15
15
|
|
16
16
|
def mysql_restart
|
17
|
-
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_RESTART'] || 'sudo
|
17
|
+
cmd = ENV['ACTIVERECORD_MYSQL_RECONNECT_MYSQL_RESTART'] || 'sudo killall -9 mysqld; sleep 3; sudo service mysql restart'
|
18
18
|
system(cmd)
|
19
19
|
end
|
20
20
|
|
@@ -22,6 +22,58 @@ class Mysql2::Client
|
|
22
22
|
def escape(str); str; end
|
23
23
|
end
|
24
24
|
|
25
|
+
class Mysql2::Error
|
26
|
+
def message
|
27
|
+
$mysql2_error_message || super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def mysql2_error(message)
|
32
|
+
begin
|
33
|
+
$mysql2_error_message = message
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
$mysql2_error_message = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def disable_retry
|
41
|
+
begin
|
42
|
+
expect(ActiveRecord::Base.enable_retry).to be_true
|
43
|
+
ActiveRecord::Base.enable_retry = false
|
44
|
+
yield
|
45
|
+
ensure
|
46
|
+
ActiveRecord::Base.enable_retry = true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def enable_read_only
|
51
|
+
begin
|
52
|
+
expect(ActiveRecord::Base.retry_read_only).to be_false
|
53
|
+
ActiveRecord::Base.retry_read_only = true
|
54
|
+
yield
|
55
|
+
ensure
|
56
|
+
ActiveRecord::Base.retry_read_only = false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def thread_run
|
61
|
+
thread_running = false
|
62
|
+
do_stop = proc { thread_running = false }
|
63
|
+
|
64
|
+
th = Thread.start {
|
65
|
+
thread_running = true
|
66
|
+
yield(do_stop)
|
67
|
+
thread_running = false
|
68
|
+
}
|
69
|
+
|
70
|
+
th.abort_on_exception = true
|
71
|
+
sleep 3
|
72
|
+
expect(thread_running).to be_true
|
73
|
+
|
74
|
+
return th
|
75
|
+
end
|
76
|
+
|
25
77
|
RSpec.configure do |config|
|
26
78
|
config.before(:each) do
|
27
79
|
employees_sql = File.expand_path('../employees.sql', __FILE__)
|
@@ -38,5 +90,6 @@ RSpec.configure do |config|
|
|
38
90
|
ActiveRecord::Base.logger.formatter = proc {|_, _, _, message| "#{message}\n" }
|
39
91
|
ActiveRecord::Base.enable_retry = true
|
40
92
|
ActiveRecord::Base.execution_tries = 10
|
93
|
+
ActiveRecord::Base.retry_read_only = false
|
41
94
|
end
|
42
95
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-mysql-reconnect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Sugawara
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - '>='
|
17
|
+
- - ! '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - '>='
|
24
|
+
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mysql2
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -56,28 +56,28 @@ dependencies:
|
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - '>='
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - '>='
|
66
|
+
- - ! '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - '>='
|
73
|
+
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 2.14.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - '>='
|
80
|
+
- - ! '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 2.14.1
|
83
83
|
description: It is the library to reconnect automatically when ActiveRecord is disconnected
|
@@ -90,6 +90,7 @@ extra_rdoc_files: []
|
|
90
90
|
files:
|
91
91
|
- .gitignore
|
92
92
|
- .rspec
|
93
|
+
- ChangeLog
|
93
94
|
- Gemfile
|
94
95
|
- LICENSE.txt
|
95
96
|
- README.md
|
@@ -115,17 +116,17 @@ require_paths:
|
|
115
116
|
- lib
|
116
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
118
|
requirements:
|
118
|
-
- - '>='
|
119
|
+
- - ! '>='
|
119
120
|
- !ruby/object:Gem::Version
|
120
121
|
version: '0'
|
121
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
123
|
requirements:
|
123
|
-
- - '>='
|
124
|
+
- - ! '>='
|
124
125
|
- !ruby/object:Gem::Version
|
125
126
|
version: '0'
|
126
127
|
requirements: []
|
127
128
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.1.11
|
129
130
|
signing_key:
|
130
131
|
specification_version: 4
|
131
132
|
summary: It is the library to reconnect automatically when ActiveRecord is disconnected
|