ebisu_connection 2.3.1 → 2.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da5ec811acbf00ad3651bfe1af53a4dc4055fa85
4
- data.tar.gz: 4f0d482ae1b9b120df97a21db4df60abf8203fd5
3
+ metadata.gz: 8c6241ca58f74a40f35eeabbead0c1a09b0123b5
4
+ data.tar.gz: 69e07131acae59f06805441cc3e79b8f6b370776
5
5
  SHA512:
6
- metadata.gz: 8bc1efc861bc74c3211ea3737a3c6a2ca63717c75155b87e9b590fe64e83b5892b2d678d13c6d048dd7d40c9959715f12a2bcdb49d2c2aea49eaf18a8da49bb8
7
- data.tar.gz: 51da097053bdfc3fc4740ee3066808516598becff46c0ba6b1ce50337f605931b1b0addeb1aec041c4350e01f1f77308dea2fbb085f9b6d6ebf0229965cc5402
6
+ metadata.gz: 41281a706b834dd6c92d97774019a871f9bc416c33f701b5fa10935cd41e4c1e6c5b6bcdc311c873e2da40202022d00170467b73a09e14c1f9c269eecf43f1c8
7
+ data.tar.gz: 831357fd7126ee7765c92240aa5e65397e0f14e358cb096b98b48147a97a1f327311428f3d1fbf68bbe7446ba3eef19031b746082f6831f2dcd7849ae77a6977
data/.travis.yml CHANGED
@@ -11,16 +11,13 @@ before_script:
11
11
  - psql -c 'create database ebisu_connection_test_replica;' -U postgres
12
12
  cache: bundler
13
13
  rvm:
14
- - 2.1.10
15
- - 2.2.6
16
- - 2.3.3
17
- - 2.4.0
14
+ - 2.2.7
15
+ - 2.3.4
16
+ - 2.4.1
18
17
  gemfile:
19
18
  - gemfiles/rails42.gemfile
20
19
  - gemfiles/rails50.gemfile
20
+ - gemfiles/rails51.gemfile
21
21
  matrix:
22
- exclude:
23
- - rvm: 2.1.10
24
- gemfile: gemfiles/rails50.gemfile
25
22
  fast_finish: true
26
23
  bundler_args: --jobs 3 --retry 3
data/Appraisals CHANGED
@@ -1,9 +1,20 @@
1
1
  appraise "rails42" do
2
2
  gem "activerecord", "~> 4.2.0"
3
- gem 'mysql2', '~> 0.3.13'
3
+ gem 'activesupport', '~> 4.2.0'
4
+ gem 'mysql2', '>= 0.3.13', '< 0.5'
5
+ gem 'pg', '~> 0.15'
4
6
  end
5
7
 
6
8
  appraise "rails50" do
7
- gem "activerecord", "5.0.0"
9
+ gem "activerecord", "~> 5.0.0"
10
+ gem 'activesupport', '~> 5.0.0'
8
11
  gem 'mysql2', '>= 0.3.18', '< 0.5'
12
+ gem 'pg', '~> 0.18'
13
+ end
14
+
15
+ appraise "rails51" do
16
+ gem 'activerecord', '~> 5.1.0'
17
+ gem 'activesupport', '~> 5.1.0'
18
+ gem 'mysql2', '>= 0.3.18', '< 0.5'
19
+ gem 'pg', '~> 0.18'
9
20
  end
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.required_ruby_version = '>= 2.1'
22
+ spec.required_ruby_version = '>= 2.2'
23
23
 
24
- spec.add_dependency 'fresh_connection', '~> 2.3.0'
24
+ spec.add_dependency 'fresh_connection', '2.4.0.rc3'
25
25
  spec.add_dependency 'concurrent-ruby', '~> 1.0.0'
26
26
 
27
27
  spec.add_development_dependency 'mysql2', '>= 0.3.13', '< 0.5'
@@ -3,6 +3,8 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 4.2.0"
6
- gem "mysql2", "~> 0.3.13"
6
+ gem "activesupport", "~> 4.2.0"
7
+ gem "mysql2", ">= 0.3.13", "< 0.5"
8
+ gem "pg", "~> 0.15"
7
9
 
8
10
  gemspec path: "../"
@@ -2,7 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "5.0.0"
5
+ gem "activerecord", "~> 5.0.0"
6
+ gem "activesupport", "~> 5.0.0"
6
7
  gem "mysql2", ">= 0.3.18", "< 0.5"
8
+ gem "pg", "~> 0.18"
7
9
 
8
10
  gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.1.0"
6
+ gem "activesupport", "~> 5.1.0"
7
+ gem "mysql2", ">= 0.3.18", "< 0.5"
8
+ gem "pg", "~> 0.18"
9
+
10
+ gemspec path: "../"
@@ -4,106 +4,60 @@ require 'active_support/deprecation'
4
4
  module EbisuConnection
5
5
  class ConfFile
6
6
  class << self
7
- attr_writer :replica_file, :check_interval
7
+ attr_writer :replica_file
8
8
 
9
9
  def slaves_file=(file)
10
10
  ActiveSupport::Deprecation.warn(
11
- "'slaves_file=' is deprecated and will removed from version 2.4.0. use 'replica_file=' insted."
11
+ "'slaves_file=' is deprecated and will removed from version 2.5.0. use 'replica_file=' instead."
12
12
  )
13
13
 
14
14
  self.replica_file = file
15
15
  end
16
16
 
17
- def if_modify
18
- if time_to_check? && modify?
19
- yield
20
- end
21
- end
22
-
23
- def conf_clear!
24
- @replica_conf = nil
25
- end
26
-
27
- def replica_conf(replica_group)
28
- @replica_conf ||= get_replica_conf
17
+ def replica_conf(spec_name)
18
+ return config unless config.is_a?(Hash)
29
19
 
30
- if @replica_conf.is_a?(Hash)
31
- c = @replica_conf[replica_group]
20
+ c = config[spec_name]
21
+ return c if c
32
22
 
33
- if !c && replica_group == "replica" && @replica_conf.key?("slave")
34
- ActiveSupport::Deprecation.warn(
35
- "'slave' in replica.yml is deprecated and will ignored from version 2.4.0. use 'replica' insted."
36
- )
23
+ if spec_name == "replica" && config.key?("slave")
24
+ ActiveSupport::Deprecation.warn(
25
+ "'slave' in replica.yml is deprecated and will ignored from version 2.5.0. use 'replica' insted."
26
+ )
37
27
 
38
- c = @replica_conf["slave"]
39
- end
40
-
41
- c || @replica_conf
42
- else
43
- @replica_conf
28
+ c = config["slave"]
44
29
  end
30
+
31
+ c || config
45
32
  end
46
33
 
47
- def slaves_conf(replica_group)
48
- ActiveSupport::Deprecation.warn(
49
- "'slaves_conf' is deprecated and will removed from version 2.4.0. use 'replica_conf' insted."
50
- )
34
+ private
35
+
36
+ def config
37
+ return @config if defined?(@config)
51
38
 
52
- replica_conf(replica_group)
39
+ conf = YAML.load_file(replica_file)
40
+ @config = conf[EbisuConnection.env.to_s] || {}
53
41
  end
54
42
 
55
43
  def replica_file
56
44
  return @replica_file if @replica_file
45
+
57
46
  raise "nothing replica_file. You have to set a file path using EbisuConnection.replica_file= method" unless defined?(Rails)
58
47
 
59
48
  file = %w(yml yaml).map{|ext| Rails.root.join("config/replica.#{ext}").to_s }.detect {|f| File.exist?(f) }
49
+ return file if file
60
50
 
61
- unless file
62
- file = %w(yml yaml).map{|ext| Rails.root.join("config/slave.#{ext}").to_s }.detect {|f| File.exist?(f) }
63
- if file
64
- ActiveSupport::Deprecation.warn(
65
- "file name 'config/#{file}' is deprecated and will ignored from version 2.4.0. use 'config/replica.yml' insted."
66
- )
67
- end
68
- end
69
-
70
- raise "nothing replica_file. You have to put a config/replica.yml file" unless file
71
-
72
- @replica_file = file
73
- end
51
+ file = %w(yml yaml).map{|ext| Rails.root.join("config/slave.#{ext}").to_s }.detect {|f| File.exist?(f) }
52
+ if file
53
+ ActiveSupport::Deprecation.warn(
54
+ "file name 'config/#{file}' is deprecated and will ignored from version 2.5.0. use 'config/replica.yml' insted."
55
+ )
74
56
 
75
- def slaves_file
76
- ActiveSupport::Deprecation.warn(
77
- "'slaves_file' is deprecated and will removed from version 2.4.0. use 'replica_file' insted."
78
- )
79
-
80
- replica_file
81
- end
82
-
83
- def check_interval
84
- @check_interval || 1.minute
85
- end
86
-
87
- private
88
-
89
- def time_to_check?
90
- now = Time.now
91
- @check_time ||= now
92
-
93
- return false if now - @check_time < check_interval
94
-
95
- @check_time = now
96
- true
97
- end
98
-
99
- def modify?
100
- @file_mtime != File.mtime(replica_file)
101
- end
57
+ return file
58
+ end
102
59
 
103
- def get_replica_conf
104
- @file_mtime = File.mtime(replica_file)
105
- conf = YAML.load_file(replica_file)
106
- conf[EbisuConnection.env.to_s] || {}
60
+ raise "nothing replica_file. You have to put a config/replica.yml file"
107
61
  end
108
62
  end
109
63
  end
@@ -1,76 +1,70 @@
1
1
  require "concurrent"
2
- require "ebisu_connection/replica_group"
2
+ require "ebisu_connection/replica"
3
+ require "ebisu_connection/greatest_common_divisor"
3
4
 
4
5
  module EbisuConnection
5
6
  class ConnectionManager < FreshConnection::AbstractConnectionManager
6
- def initialize(replica_group = "replica")
7
+ class AllReplicaHasGoneError < StandardError; end
8
+
9
+ def initialize(spec_name = nil)
7
10
  super
8
- @replicas = Concurrent::Map.new
11
+
12
+ @replicas = Concurrent::Array.new
13
+
14
+ replica_conf.each do |conf|
15
+ @replicas << Replica.new(conf, spec_name)
16
+ end
17
+
18
+ recalc_roulette
9
19
  end
10
20
 
11
21
  def replica_connection
12
- replicas.sample.connection
22
+ raise AllReplicaHasGoneError if @replicas.empty?
23
+ @replicas[@roulette.sample].connection
13
24
  end
14
25
 
15
26
  def put_aside!
16
- return if check_own_connection
17
-
18
- ConfFile.if_modify do
19
- reserve_release_all_connection
20
- check_own_connection
27
+ @replicas.each_value do |pool|
28
+ pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
21
29
  end
22
30
  end
23
31
 
24
32
  def clear_all_connections!
25
- @replicas.each_value do |s|
26
- s.all_disconnect!
33
+ @replicas.each_value do |pool|
34
+ pool.disconnect!
27
35
  end
28
-
29
- @replicas.clear
30
- ConfFile.conf_clear!
31
36
  end
32
37
 
33
38
  def recovery?
34
- replicas.recovery_connection?
35
- end
39
+ dead_replicas = @replicas.select{|pool| !pool.connection.active? }
40
+ return false if dead_replicas.empty?
36
41
 
37
- private
42
+ dead_replicas.each do |pool|
43
+ pool.disconnect!
44
+ @replicas.delete(pool)
45
+ end
38
46
 
39
- def check_own_connection
40
- s = @replicas[current_thread_id]
47
+ raise AllReplicaHasGoneError if @replicas.empty?
41
48
 
42
- if s && s.reserved_release?
43
- s.all_disconnect!
44
- @replicas.delete(current_thread_id)
45
- true
46
- else
47
- false
48
- end
49
+ recalc_roulette
50
+ true
49
51
  end
50
52
 
51
- def reserve_release_all_connection
52
- @replicas.each_value do |s|
53
- s.reserve_release_connection!
54
- end
55
- ConfFile.conf_clear!
56
- end
53
+ private
57
54
 
58
- def replicas
59
- @replicas.fetch_or_store(current_thread_id) do |_|
60
- get_replicas
61
- end
62
- end
55
+ def recalc_roulette
56
+ weight_list = @replicas.map {|pool| pool.weight }
63
57
 
64
- def get_replicas
65
- ReplicaGroup.new(replica_conf, replica_group)
58
+ @roulette = []
59
+ gcd = GreatestCommonDivisor.calc(weight_list)
60
+ weight_list.each_with_index do |w, index|
61
+ weight = w / gcd
62
+ @roulette.concat([index] * weight)
63
+ end
66
64
  end
67
65
 
68
66
  def replica_conf
69
- ConfFile.replica_conf(replica_group)
70
- end
71
-
72
- def current_thread_id
73
- Thread.current.object_id
67
+ ConfFile.replica_conf(spec_name)
74
68
  end
75
69
  end
76
70
  end
@@ -0,0 +1,9 @@
1
+ module EbisuConnection
2
+ class Railtie < Rails::Railtie
3
+ initializer "fresh_connection.initialize_database", after: "active_record.initialize_database" do
4
+ ActiveSupport.on_load(:active_record) do
5
+ ActiveRecord::Base.establish_fresh_connection
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,45 +1,54 @@
1
+ require 'fresh_connection/connection_specification'
2
+
1
3
  module EbisuConnection
2
4
  class Replica
3
5
  attr_reader :hostname, :weight
4
6
 
5
- def initialize(conf, replica_group)
7
+ def initialize(conf, spec_name)
6
8
  case conf
7
9
  when String
8
10
  host, weight = conf.split(/\s*,\s*/)
9
- @hostname, port = host.split(/\s*:\s*/)
11
+ @hostname, @port = host.split(/\s*:\s*/)
10
12
  when Hash
11
13
  @hostname = conf["host"] || conf[:host]
12
14
  weight = conf["weight"] || conf[:weight]
13
- port = conf["port"] || conf[:port]
15
+ @port = conf["port"] || conf[:port]
14
16
  else
15
17
  raise ArgumentError, "replica config is invalid"
16
18
  end
17
19
 
18
- spec = modify_spec(port)
19
- @connection_factory = FreshConnection::ConnectionFactory.new(replica_group, spec)
20
+ spec = FreshConnection::ConnectionSpecification.new(
21
+ spec_name, modify_spec: modify_spec
22
+ ).spec
23
+
24
+ @pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
20
25
  @weight = (weight || 1).to_i
21
26
  end
22
27
 
23
28
  def connection
24
- @connection ||= @connection_factory.new_connection
29
+ @pool.connection
30
+ end
31
+
32
+ def active_connection?
33
+ @pool.active_connection?
25
34
  end
26
35
 
27
- def active?
28
- connection.active?
36
+ def release_connection
37
+ @pool.release_connection
29
38
  end
30
39
 
31
40
  def disconnect!
32
- if @connection
33
- @connection.disconnect!
34
- @connection = nil
35
- end
36
- rescue
41
+ @pool.disconnect!
37
42
  end
38
43
 
39
- def modify_spec(port)
44
+ private
45
+
46
+ def modify_spec
40
47
  modify_spec = {"host" => @hostname}
41
- return modify_spec unless port
42
- modify_spec["port"] = port.to_i if port.is_a?(Integer) || !port.empty?
48
+ return modify_spec if !defined?(@port) || @port.nil?
49
+ return modify_spec if @port.respond_to?(:empty?) && @port.empty?
50
+
51
+ modify_spec["port"] = @port.to_i
43
52
  modify_spec
44
53
  end
45
54
  end
@@ -1,3 +1,3 @@
1
1
  module EbisuConnection
2
- VERSION = "2.3.1"
2
+ VERSION = "2.4.0.rc1"
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/deprecation'
1
+ require 'active_support'
2
2
  require "fresh_connection"
3
3
  require "ebisu_connection/conf_file"
4
4
 
@@ -11,15 +11,7 @@ module EbisuConnection
11
11
  end
12
12
 
13
13
  def slaves_file=(file)
14
- ActiveSupport::Deprecation.warn(
15
- "'slaves_file=' is deprecated and will removed from version 2.4.0. use 'replica_file=' insted."
16
- )
17
-
18
- self.replica_file = file
19
- end
20
-
21
- def check_interval=(interval)
22
- ConfFile.check_interval = interval
14
+ ConfFile.slaves_file = file
23
15
  end
24
16
 
25
17
  def env
@@ -30,4 +22,5 @@ end
30
22
 
31
23
  require "ebisu_connection/connection_manager"
32
24
  FreshConnection.connection_manager = EbisuConnection::ConnectionManager
33
- ActiveRecord::Base.establish_fresh_connection
25
+
26
+ require "ebisu_connection/railtie" if defined?(Rails)
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ebisu_connection
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - tsukasaoishi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-20 00:00:00.000000000 Z
11
+ date: 2017-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fresh_connection
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.3.0
19
+ version: 2.4.0.rc3
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
- version: 2.3.0
26
+ version: 2.4.0.rc3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: concurrent-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -169,12 +169,13 @@ files:
169
169
  - ebisu_connection.gemspec
170
170
  - gemfiles/rails42.gemfile
171
171
  - gemfiles/rails50.gemfile
172
+ - gemfiles/rails51.gemfile
172
173
  - lib/ebisu_connection.rb
173
174
  - lib/ebisu_connection/conf_file.rb
174
175
  - lib/ebisu_connection/connection_manager.rb
175
176
  - lib/ebisu_connection/greatest_common_divisor.rb
177
+ - lib/ebisu_connection/railtie.rb
176
178
  - lib/ebisu_connection/replica.rb
177
- - lib/ebisu_connection/replica_group.rb
178
179
  - lib/ebisu_connection/version.rb
179
180
  homepage: https://github.com/tsukasaoishi/ebisu_connection
180
181
  licenses:
@@ -188,15 +189,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
189
  requirements:
189
190
  - - ">="
190
191
  - !ruby/object:Gem::Version
191
- version: '2.1'
192
+ version: '2.2'
192
193
  required_rubygems_version: !ruby/object:Gem::Requirement
193
194
  requirements:
194
- - - ">="
195
+ - - ">"
195
196
  - !ruby/object:Gem::Version
196
- version: '0'
197
+ version: 1.3.1
197
198
  requirements: []
198
199
  rubyforge_project:
199
- rubygems_version: 2.5.2
200
+ rubygems_version: 2.6.11
200
201
  signing_key:
201
202
  specification_version: 4
202
203
  summary: EbisuConnection supports connections with configured replica servers.
@@ -1,62 +0,0 @@
1
- require "ebisu_connection/replica"
2
- require "ebisu_connection/greatest_common_divisor"
3
-
4
- module EbisuConnection
5
- class ReplicaGroup
6
- class AllReplicaHasGoneError < StandardError; end
7
-
8
- def initialize(replica_conf, replica_group)
9
- @replicas = replica_conf.map do |conf|
10
- Replica.new(conf, replica_group)
11
- end
12
-
13
- recalc_roulette
14
- end
15
-
16
- def sample
17
- raise AllReplicaHasGoneError if @replicas.empty?
18
- @replicas[@roulette.sample]
19
- end
20
-
21
- def recovery_connection?
22
- dead_replicas = @replicas.select{|s| !s.active? }
23
- return false if dead_replicas.empty?
24
-
25
- dead_replicas.each do |s|
26
- s.disconnect!
27
- @replicas.delete(s)
28
- end
29
-
30
- raise AllReplicaHasGoneError if @replicas.empty?
31
-
32
- recalc_roulette
33
- true
34
- end
35
-
36
- def all_disconnect!
37
- @reserve_release = nil
38
- @replicas.each {|s| s.disconnect!}
39
- end
40
-
41
- def reserve_release_connection!
42
- @reserve_release = true
43
- end
44
-
45
- def reserved_release?
46
- !!@reserve_release
47
- end
48
-
49
- private
50
-
51
- def recalc_roulette
52
- weight_list = @replicas.map {|s| s.weight }
53
-
54
- @roulette = []
55
- gcd = GreatestCommonDivisor.calc(weight_list)
56
- weight_list.each_with_index do |w, index|
57
- weight = w / gcd
58
- @roulette.concat([index] * weight)
59
- end
60
- end
61
- end
62
- end