activerecord-mysql-reconnect 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|