ar_mysql_flexmaster 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,9 +10,6 @@ module ActiveRecord
10
10
 
11
11
  # fallback to :host or :localhost
12
12
  config[:hosts] ||= config.key?(:host) ? [config[:host]] : ['localhost']
13
-
14
- hosts = config[:hosts] || [config[:host]]
15
-
16
13
  config[:username] = 'root' if config[:username].nil?
17
14
 
18
15
  if Mysql2::Client.const_defined? :FOUND_ROWS
@@ -119,13 +116,16 @@ module ActiveRecord
119
116
  end
120
117
  end
121
118
 
122
- AR_MESSAGES = [ /^Mysql2::Error: MySQL server has gone away/,
123
- /^Mysql2::Error: Can't connect to MySQL server/ ]
119
+ AR_MESSAGES = [/^Mysql2::Error: MySQL server has gone away/,
120
+ /^Mysql2::Error: Lost connection to MySQL server during query/,
121
+ /^Mysql2::Error: Can't connect to MySQL server/]
124
122
  def retryable_error?(e)
125
123
  case e
126
124
  when Mysql2::Error
127
- # 2006 is gone-away, 2003 is can't-connect (applicable when reconnect is true)
128
- [2006, 2003].include?(e.errno)
125
+ # 2006 is gone-away
126
+ # 2013 is lost connection during query
127
+ # 2003 is can't-connect (applicable when reconnect is true)
128
+ [2006, 2013, 2003].include?(e.errno)
129
129
  when ActiveRecord::StatementInvalid
130
130
  AR_MESSAGES.any? { |m| e.message.match(m) }
131
131
  end
@@ -194,12 +194,14 @@ module ActiveRecord
194
194
  sleep_interval = 0.1
195
195
  timeout_at = Time.now.to_f + @tx_hold_timeout
196
196
 
197
- begin
197
+ loop do
198
198
  @connection = find_correct_host(@rw)
199
199
  return if @connection
200
200
 
201
201
  sleep(sleep_interval)
202
- end while Time.now.to_f < timeout_at
202
+
203
+ break unless Time.now.to_f < timeout_at
204
+ end
203
205
 
204
206
  raise_no_server_available!
205
207
  end
@@ -250,7 +252,7 @@ module ActiveRecord
250
252
  def initialize_connection(host, port)
251
253
  attempts = 1
252
254
  begin
253
- Timeout::timeout(@connection_timeout) do
255
+ Timeout.timeout(@connection_timeout) do
254
256
  cfg = @config.merge(:host => host, :port => port)
255
257
  Mysql2::Client.new(cfg).tap do |cx|
256
258
  cx.query_options.merge!(:as => :array)
@@ -13,7 +13,7 @@ end
13
13
  require_relative 'boot_mysql_env'
14
14
 
15
15
  File.open(File.dirname(File.expand_path(__FILE__)) + "/database.yml", "w+") do |f|
16
- f.write <<-EOL
16
+ f.write <<-EOL
17
17
  common: &common
18
18
  adapter: mysql_flexmaster
19
19
  username: flex
@@ -38,7 +38,7 @@ reconnect_slave:
38
38
  EOL
39
39
  end
40
40
 
41
- ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
41
+ ActiveRecord::Base.configurations = YAML.load(IO.read(File.dirname(__FILE__) + '/database.yml'))
42
42
  ActiveRecord::Base.establish_connection(:test)
43
43
 
44
44
  class User < ActiveRecord::Base
@@ -94,7 +94,7 @@ class TestArFlexmaster < Minitest::Test
94
94
 
95
95
  $mysql_master.set_rw(false)
96
96
  start_time = Time.now.to_i
97
- e = assert_raises(ActiveRecord::ConnectionAdapters::MysqlFlexmasterAdapter::NoServerAvailableException) do
97
+ assert_raises(ActiveRecord::ConnectionAdapters::MysqlFlexmasterAdapter::NoServerAvailableException) do
98
98
  User.create(:name => "foo")
99
99
  end
100
100
  end_time = Time.now.to_i
@@ -113,7 +113,7 @@ class TestArFlexmaster < Minitest::Test
113
113
  if ActiveRecord::VERSION::MAJOR >= 4
114
114
  assert User.where(:name => "foo").exists?
115
115
  else
116
- assert User.first(:conditions => {:name => "foo"})
116
+ assert User.first(:conditions => { :name => "foo" })
117
117
  end
118
118
  end
119
119
 
@@ -146,7 +146,7 @@ class TestArFlexmaster < Minitest::Test
146
146
  $mysql_slave.set_rw(true)
147
147
  assert_equal $mysql_master, master_connection
148
148
  100.times do
149
- u = User.first
149
+ User.first
150
150
  end
151
151
  assert_equal $mysql_slave, master_connection
152
152
  end
@@ -159,7 +159,7 @@ class TestArFlexmaster < Minitest::Test
159
159
  $mysql_slave.set_rw(false)
160
160
  assert_equal $mysql_master, master_connection
161
161
  100.times do
162
- u = User.first
162
+ User.first
163
163
  end
164
164
  end
165
165
 
@@ -295,7 +295,10 @@ class TestArFlexmaster < Minitest::Test
295
295
  null_logger = Logger.new('/dev/null')
296
296
  config = { hosts: ['localhost'], connection_timeout: 0.01, connection_attempts: 5 }
297
297
 
298
- Mysql2::Client.stubs(:new).with { attempts += 1; sleep 1 }
298
+ Mysql2::Client.stubs(:new).with do
299
+ attempts += 1
300
+ sleep 1
301
+ end
299
302
  assert_raises(ActiveRecord::ConnectionAdapters::MysqlFlexmasterAdapter::NoServerAvailableException) do
300
303
  ActiveRecord::ConnectionAdapters::MysqlFlexmasterAdapter.new(null_logger, config)
301
304
  end
@@ -1,25 +1,25 @@
1
- # frozen_string_literal: true
2
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
3
 
4
- require "mysql_isolated_server"
4
+ require "isolated_server"
5
5
 
6
6
  threads = []
7
7
  threads << Thread.new do
8
- $mysql_master = MysqlIsolatedServer.new(allow_output: false)
8
+ $mysql_master = IsolatedServer::Mysql.new(allow_output: false)
9
9
  $mysql_master.boot!
10
10
 
11
11
  puts "mysql master booted on port #{$mysql_master.port} -- access with mysql -uroot -h127.0.0.1 --port=#{$mysql_master.port} mysql"
12
12
  end
13
13
 
14
14
  threads << Thread.new do
15
- $mysql_slave = MysqlIsolatedServer.new
15
+ $mysql_slave = IsolatedServer::Mysql.new
16
16
  $mysql_slave.boot!
17
17
 
18
18
  puts "mysql slave booted on port #{$mysql_slave.port} -- access with mysql -uroot -h127.0.0.1 --port=#{$mysql_slave.port} mysql"
19
19
  end
20
20
 
21
21
  threads << Thread.new do
22
- $mysql_slave_2 = MysqlIsolatedServer.new
22
+ $mysql_slave_2 = IsolatedServer::Mysql.new
23
23
  $mysql_slave_2.boot!
24
24
 
25
25
  puts "mysql chained slave booted on port #{$mysql_slave_2.port} -- access with mysql -uroot -h127.0.0.1 --port=#{$mysql_slave_2.port} mysql"
@@ -1,16 +1,16 @@
1
- require_relative 'mysql_isolated_server'
1
+ require_relative 'isolated_server'
2
2
 
3
3
  # yeah, not technically isolated
4
- master = MysqlIsolatedServer.new(port: 3306)
4
+ master = IsolatedServer::Mysql.new(port: 3306)
5
5
 
6
- slave = MysqlIsolatedServer.new(data_path: "/Users/ben/.zendesk/var/mysql", allow_output: true, params: "--relay-log=footwa --skip-slave-start", port: 41756)
6
+ slave = IsolatedServer::Mysql.new(data_path: "/Users/ben/.zendesk/var/mysql", allow_output: true, params: "--relay-log=footwa --skip-slave-start", port: 41756)
7
7
  slave.boot!
8
8
  puts "mysql slave booted on port #{slave.port} -- access with mysql -uroot -h127.0.0.1 --port=#{slave.port} mysql"
9
9
  slave.connection.query("set global server_id=123")
10
10
  slave.make_slave_of(master)
11
11
  slave.set_rw(false)
12
12
 
13
- uid_server = MysqlIsolatedServer.new(data_path: "/Users/ben/.zendesk/var/mysql", allow_output: true, params: "--skip-slave-start", port: 41757)
13
+ uid_server = IsolatedServer::Mysql.new(data_path: "/Users/ben/.zendesk/var/mysql", allow_output: true, params: "--skip-slave-start", port: 41757)
14
14
  uid_server.boot!
15
15
  puts "mysql uid server booted on port #{uid_server.port} -- access with mysql -uroot -h127.0.0.1 --port=#{uid_server.port} mysql"
16
16
  sleep
@@ -13,4 +13,3 @@ class NoTrafficTest < Minitest::Test
13
13
  assert_ro($mysql_slave.connection, 'master', false)
14
14
  end
15
15
  end
16
-
@@ -12,7 +12,7 @@ class WithKillableQueries < Minitest::Test
12
12
  $mysql_master.connection.query("update flexmaster_test.users set name=sleep(600)")
13
13
  assert false, "Query did not get killed! Bad."
14
14
  exit 1
15
- rescue Exception => e
15
+ rescue StandardError => e
16
16
  puts e
17
17
  end
18
18
  }
@@ -19,7 +19,7 @@ class WrongSetupTest < Minitest::Test
19
19
  puts "testing cutover with stopped slave"
20
20
  $mysql_master.connection.query("set GLOBAL READ_ONLY=0")
21
21
  $mysql_slave.connection.query("set GLOBAL READ_ONLY=1")
22
- $mysql_slave.connection.query("slave stop")
22
+ $mysql_slave.connection.query("STOP SLAVE")
23
23
  assert_script_failed
24
24
  end
25
25
  end
@@ -11,10 +11,9 @@ require_relative 'boot_mysql_env'
11
11
 
12
12
  def assert_ro(cx, str, bool)
13
13
  expected = bool ? 1 : 0
14
- assert_equal expected, cx.query("select @@read_only as ro").first['ro'], "#{str} is #{bool ? 'read-write' : 'read-only'} but I expected otherwise!"
14
+ assert_equal expected, cx.query("select @@read_only as ro").first['ro'], "#{str} is #{bool ? 'read-write' : 'read-only'} but I expected otherwise!"
15
15
  end
16
16
 
17
17
  def master_cut_script
18
18
  File.expand_path(File.dirname(__FILE__)) + "/../bin/master_cut"
19
19
  end
20
-
metadata CHANGED
@@ -1,14 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_mysql_flexmaster
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Osheroff
8
+ - Benjamin Quorning
9
+ - Gabe Martin-Dempesy
10
+ - Michael Grosser
11
+ - Pierre Schambacher
8
12
  autorequire:
9
13
  bindir: bin
10
14
  cert_chain: []
11
- date: 2016-05-13 00:00:00.000000000 Z
15
+ date: 2017-11-10 00:00:00.000000000 Z
12
16
  dependencies:
13
17
  - !ruby/object:Gem::Dependency
14
18
  name: mysql2
@@ -52,6 +56,20 @@ dependencies:
52
56
  - - ">="
53
57
  - !ruby/object:Gem::Version
54
58
  version: '0'
59
+ - !ruby/object:Gem::Dependency
60
+ name: bundler
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
55
73
  - !ruby/object:Gem::Dependency
56
74
  name: rake
57
75
  requirement: !ruby/object:Gem::Requirement
@@ -137,23 +155,26 @@ dependencies:
137
155
  - !ruby/object:Gem::Version
138
156
  version: '0'
139
157
  - !ruby/object:Gem::Dependency
140
- name: mysql_isolated_server
158
+ name: isolated_server
141
159
  requirement: !ruby/object:Gem::Requirement
142
160
  requirements:
143
- - - "~>"
161
+ - - ">="
144
162
  - !ruby/object:Gem::Version
145
- version: '0.5'
163
+ version: '0'
146
164
  type: :development
147
165
  prerelease: false
148
166
  version_requirements: !ruby/object:Gem::Requirement
149
167
  requirements:
150
- - - "~>"
168
+ - - ">="
151
169
  - !ruby/object:Gem::Version
152
- version: '0.5'
170
+ version: '0'
153
171
  description: ar_mysql_flexmaster allows configuring N mysql servers in database.yml
154
172
  and auto-selects which is a master at runtime
155
173
  email:
156
- - ben@zendesk.com
174
+ - bquorning@zendesk.com
175
+ - gabe@zendesk.com
176
+ - mgrosser@zendesk.com
177
+ - pschambacher@zendesk.com
157
178
  executables:
158
179
  - master_cut
159
180
  extensions: []
@@ -169,10 +190,6 @@ files:
169
190
  - bin/master_cut
170
191
  - gemfiles/rails3.2.gemfile
171
192
  - gemfiles/rails3.2.gemfile.lock
172
- - gemfiles/rails4.0.gemfile
173
- - gemfiles/rails4.0.gemfile.lock
174
- - gemfiles/rails4.1.gemfile
175
- - gemfiles/rails4.1.gemfile.lock
176
193
  - gemfiles/rails4.2.gemfile
177
194
  - gemfiles/rails4.2.gemfile.lock
178
195
  - gemfiles/rails5.0.gemfile
@@ -189,7 +206,7 @@ files:
189
206
  - test/integration/wrong_setup_test.rb
190
207
  - test/integration_helper.rb
191
208
  - unplanned_failovers.md
192
- homepage: http://github.com/osheroff/ar_mysql_flexmaster
209
+ homepage: http://github.com/zendesk/ar_mysql_flexmaster
193
210
  licenses: []
194
211
  metadata: {}
195
212
  post_install_message:
@@ -200,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
217
  requirements:
201
218
  - - ">="
202
219
  - !ruby/object:Gem::Version
203
- version: '0'
220
+ version: '2.2'
204
221
  required_rubygems_version: !ruby/object:Gem::Requirement
205
222
  requirements:
206
223
  - - ">="
@@ -208,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
225
  version: '0'
209
226
  requirements: []
210
227
  rubyforge_project:
211
- rubygems_version: 2.4.5.1
228
+ rubygems_version: 2.4.5.3
212
229
  signing_key:
213
230
  specification_version: 4
214
231
  summary: select a master at runtime from a list
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path => "../"
4
-
5
- gem "rails", "~> 4.0.0"
6
- gem "mysql2", "~> 0.3.0"
@@ -1,104 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- ar_mysql_flexmaster (0.6.0)
5
- activerecord
6
- activesupport
7
- mysql2
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actionmailer (4.0.13)
13
- actionpack (= 4.0.13)
14
- mail (~> 2.5, >= 2.5.4)
15
- actionpack (4.0.13)
16
- activesupport (= 4.0.13)
17
- builder (~> 3.1.0)
18
- erubis (~> 2.7.0)
19
- rack (~> 1.5.2)
20
- rack-test (~> 0.6.2)
21
- activemodel (4.0.13)
22
- activesupport (= 4.0.13)
23
- builder (~> 3.1.0)
24
- activerecord (4.0.13)
25
- activemodel (= 4.0.13)
26
- activerecord-deprecated_finders (~> 1.0.2)
27
- activesupport (= 4.0.13)
28
- arel (~> 4.0.0)
29
- activerecord-deprecated_finders (1.0.4)
30
- activesupport (4.0.13)
31
- i18n (~> 0.6, >= 0.6.9)
32
- minitest (~> 4.2)
33
- multi_json (~> 1.3)
34
- thread_safe (~> 0.1)
35
- tzinfo (~> 0.3.37)
36
- arel (4.0.2)
37
- builder (3.1.4)
38
- bump (0.5.3)
39
- coderay (1.1.0)
40
- concurrent-ruby (1.0.0)
41
- erubis (2.7.0)
42
- i18n (0.7.0)
43
- mail (2.6.3)
44
- mime-types (>= 1.16, < 3)
45
- metaclass (0.0.4)
46
- method_source (0.8.2)
47
- mime-types (2.99)
48
- minitest (4.7.5)
49
- mocha (1.1.0)
50
- metaclass (~> 0.0.1)
51
- multi_json (1.11.2)
52
- mysql2 (0.3.20)
53
- mysql_isolated_server (0.5.3)
54
- pry (0.10.3)
55
- coderay (~> 1.1.0)
56
- method_source (~> 0.8.1)
57
- slop (~> 3.4)
58
- rack (1.5.5)
59
- rack-test (0.6.3)
60
- rack (>= 1.0)
61
- rails (4.0.13)
62
- actionmailer (= 4.0.13)
63
- actionpack (= 4.0.13)
64
- activerecord (= 4.0.13)
65
- activesupport (= 4.0.13)
66
- bundler (>= 1.3.0, < 2.0)
67
- railties (= 4.0.13)
68
- sprockets-rails (~> 2.0)
69
- railties (4.0.13)
70
- actionpack (= 4.0.13)
71
- activesupport (= 4.0.13)
72
- rake (>= 0.8.7)
73
- thor (>= 0.18.1, < 2.0)
74
- rake (10.4.2)
75
- slop (3.6.0)
76
- sprockets (3.5.2)
77
- concurrent-ruby (~> 1.0)
78
- rack (> 1, < 3)
79
- sprockets-rails (2.3.3)
80
- actionpack (>= 3.0)
81
- activesupport (>= 3.0)
82
- sprockets (>= 2.8, < 4.0)
83
- thor (0.19.1)
84
- thread_safe (0.3.5)
85
- tzinfo (0.3.46)
86
- wwtd (1.3.0)
87
-
88
- PLATFORMS
89
- ruby
90
-
91
- DEPENDENCIES
92
- ar_mysql_flexmaster!
93
- bump
94
- minitest
95
- mocha (~> 1.1.0)
96
- mysql2 (~> 0.3.0)
97
- mysql_isolated_server (~> 0.5)
98
- pry
99
- rails (~> 4.0.0)
100
- rake
101
- wwtd
102
-
103
- BUNDLED WITH
104
- 1.11.2
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path => "../"
4
-
5
- gem "rails", "~> 4.1.8"
6
- gem "mysql2", "~> 0.3.0"
@@ -1,109 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- ar_mysql_flexmaster (0.6.0)
5
- activerecord
6
- activesupport
7
- mysql2
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actionmailer (4.1.14)
13
- actionpack (= 4.1.14)
14
- actionview (= 4.1.14)
15
- mail (~> 2.5, >= 2.5.4)
16
- actionpack (4.1.14)
17
- actionview (= 4.1.14)
18
- activesupport (= 4.1.14)
19
- rack (~> 1.5.2)
20
- rack-test (~> 0.6.2)
21
- actionview (4.1.14)
22
- activesupport (= 4.1.14)
23
- builder (~> 3.1)
24
- erubis (~> 2.7.0)
25
- activemodel (4.1.14)
26
- activesupport (= 4.1.14)
27
- builder (~> 3.1)
28
- activerecord (4.1.14)
29
- activemodel (= 4.1.14)
30
- activesupport (= 4.1.14)
31
- arel (~> 5.0.0)
32
- activesupport (4.1.14)
33
- i18n (~> 0.6, >= 0.6.9)
34
- json (~> 1.7, >= 1.7.7)
35
- minitest (~> 5.1)
36
- thread_safe (~> 0.1)
37
- tzinfo (~> 1.1)
38
- arel (5.0.1.20140414130214)
39
- builder (3.2.2)
40
- bump (0.5.3)
41
- coderay (1.1.0)
42
- concurrent-ruby (1.0.0)
43
- erubis (2.7.0)
44
- i18n (0.7.0)
45
- json (1.8.3)
46
- mail (2.6.3)
47
- mime-types (>= 1.16, < 3)
48
- metaclass (0.0.4)
49
- method_source (0.8.2)
50
- mime-types (2.99)
51
- minitest (5.8.3)
52
- mocha (1.1.0)
53
- metaclass (~> 0.0.1)
54
- mysql2 (0.3.20)
55
- mysql_isolated_server (0.5.3)
56
- pry (0.10.3)
57
- coderay (~> 1.1.0)
58
- method_source (~> 0.8.1)
59
- slop (~> 3.4)
60
- rack (1.5.5)
61
- rack-test (0.6.3)
62
- rack (>= 1.0)
63
- rails (4.1.14)
64
- actionmailer (= 4.1.14)
65
- actionpack (= 4.1.14)
66
- actionview (= 4.1.14)
67
- activemodel (= 4.1.14)
68
- activerecord (= 4.1.14)
69
- activesupport (= 4.1.14)
70
- bundler (>= 1.3.0, < 2.0)
71
- railties (= 4.1.14)
72
- sprockets-rails (~> 2.0)
73
- railties (4.1.14)
74
- actionpack (= 4.1.14)
75
- activesupport (= 4.1.14)
76
- rake (>= 0.8.7)
77
- thor (>= 0.18.1, < 2.0)
78
- rake (10.4.2)
79
- slop (3.6.0)
80
- sprockets (3.5.2)
81
- concurrent-ruby (~> 1.0)
82
- rack (> 1, < 3)
83
- sprockets-rails (2.3.3)
84
- actionpack (>= 3.0)
85
- activesupport (>= 3.0)
86
- sprockets (>= 2.8, < 4.0)
87
- thor (0.19.1)
88
- thread_safe (0.3.5)
89
- tzinfo (1.2.2)
90
- thread_safe (~> 0.1)
91
- wwtd (1.3.0)
92
-
93
- PLATFORMS
94
- ruby
95
-
96
- DEPENDENCIES
97
- ar_mysql_flexmaster!
98
- bump
99
- minitest
100
- mocha (~> 1.1.0)
101
- mysql2 (~> 0.3.0)
102
- mysql_isolated_server (~> 0.5)
103
- pry
104
- rails (~> 4.1.8)
105
- rake
106
- wwtd
107
-
108
- BUNDLED WITH
109
- 1.11.2