fresh_connection 2.3.2 → 2.4.0.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d6bb81775c1ffa074f52f58fad152f9d02d8498
4
- data.tar.gz: 622671bc7d23b5a88f92eb8f4430b5b15014d917
3
+ metadata.gz: d80ccd0fbc035f407e1eecd01e328f47d9651f63
4
+ data.tar.gz: 6b23a6ca48aae178e84213f12f4358e833317446
5
5
  SHA512:
6
- metadata.gz: 6a7de0aff8b2b35291005f1236bf5e6d87e4285a5d54b6619eebebf2a1edc5a83f750abfcc2795ee070edc7c97d4aec2796d5e5f3622d7293bdfab58ab829cdb
7
- data.tar.gz: 3799709992b9fbd0cb4c8cac11db8db34601fec8333dbe41bd25c51eeddadec36f5153a9fc39aa5548e373e8175e938760e471d11bae77edb04aecb63d63891b
6
+ metadata.gz: 5875734234572158f582ffba4dcaf7d7fcbc1df4a22459154ae4eea49c90cc9f825b37c4c937d42255a6a96747fc79af92cd59515e52e9d768f035bf912df8df
7
+ data.tar.gz: fc97dc485d0dfcb4b35fd57ac9242b3c5213619fc3249f9d827485c5d471ba844a7ed66c6dc4d6311f5292ca69cbf7754d1e0ddefd2486a7ae01f2a7d5900ccb
data/.travis.yml CHANGED
@@ -12,16 +12,13 @@ before_script:
12
12
  - psql -c 'create database fresh_connection_test_replica2;' -U postgres
13
13
  cache: bundler
14
14
  rvm:
15
- - 2.1.10
16
- - 2.2.6
17
- - 2.3.3
18
- - 2.4.0
15
+ - 2.2.7
16
+ - 2.3.4
17
+ - 2.4.1
19
18
  gemfile:
20
19
  - gemfiles/rails42.gemfile
21
20
  - gemfiles/rails50.gemfile
21
+ - gemfiles/rails51.gemfile
22
22
  matrix:
23
- exclude:
24
- - rvm: 2.1.10
25
- gemfile: gemfiles/rails50.gemfile
26
23
  fast_finish: true
27
24
  bundler_args: --jobs 3 --retry 3
data/Appraisals CHANGED
@@ -1,11 +1,20 @@
1
1
  appraise "rails42" do
2
2
  gem 'activerecord', '~> 4.2.0'
3
3
  gem 'activesupport', '~> 4.2.0'
4
- gem 'mysql2', '~> 0.3.13'
4
+ gem 'mysql2', '>= 0.3.13', '< 0.5'
5
+ gem 'pg', '~> 0.15'
5
6
  end
6
7
 
7
8
  appraise "rails50" do
8
9
  gem 'activerecord', '~> 5.0.0'
9
10
  gem 'activesupport', '~> 5.0.0'
10
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'
11
20
  end
data/Rakefile CHANGED
@@ -4,13 +4,11 @@ require 'rake/testtask'
4
4
  desc 'Run mysql2 and postgresql tests'
5
5
  task :test do
6
6
  Rake::Task["test:mysql2"].invoke
7
- Rake::Task["test:mysql2_url"].invoke
8
7
  Rake::Task["test:postgresql"].invoke
9
- Rake::Task["test:postgresql_url"].invoke
10
8
  end
11
9
 
12
10
  namespace :test do
13
- %w(mysql2 postgresql mysql2_url postgresql_url).each do |test_name|
11
+ %w(mysql2 postgresql).each do |test_name|
14
12
  Rake::TestTask.new(test_name) do |t|
15
13
  t.libs << "test"
16
14
  t.libs << "lib"
@@ -19,10 +19,10 @@ 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 'activerecord', '>= 4.2.0', '< 5.1'
25
- spec.add_dependency 'activesupport', '>= 4.2.0', '< 5.1'
24
+ spec.add_dependency 'activerecord', '>= 4.2.0', '< 5.2'
25
+ spec.add_dependency 'activesupport', '>= 4.2.0', '< 5.2'
26
26
  spec.add_dependency 'concurrent-ruby', '~> 1.0.0'
27
27
 
28
28
  spec.add_development_dependency 'mysql2', '>= 0.3.13', '< 0.5'
@@ -4,6 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 4.2.0"
6
6
  gem "activesupport", "~> 4.2.0"
7
- gem "mysql2", "~> 0.3.13"
7
+ gem "mysql2", ">= 0.3.13", "< 0.5"
8
+ gem "pg", "~> 0.15"
8
9
 
9
- gemspec :path => "../"
10
+ gemspec path: "../"
@@ -5,5 +5,6 @@ source "https://rubygems.org"
5
5
  gem "activerecord", "~> 5.0.0"
6
6
  gem "activesupport", "~> 5.0.0"
7
7
  gem "mysql2", ">= 0.3.18", "< 0.5"
8
+ gem "pg", "~> 0.18"
8
9
 
9
- gemspec :path => "../"
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: "../"
@@ -1,4 +1,5 @@
1
1
  require 'active_support/deprecation'
2
+ require 'fresh_connection/deprecation'
2
3
 
3
4
  module FreshConnection
4
5
  class AbstractConnectionManager
@@ -12,37 +13,37 @@ module FreshConnection
12
13
  end
13
14
  end
14
15
 
15
- attr_reader :replica_group
16
+ attr_reader :spec_name
16
17
 
17
- def initialize(replica_group = "replica")
18
- replica_group = "replica" if replica_group.to_s == "slave"
19
- @replica_group = replica_group.to_s
20
- @replica_group = "replica" if @replica_group.empty?
18
+ def initialize(spec_name = nil)
19
+ @spec_name = (spec_name || "replica").to_s
21
20
  end
22
21
 
23
- def slave_group
24
- ActiveSupport::Deprecation.warn(
25
- "'slave_group' is deprecated and will removed from version 2.4.0. use 'replica_group' instead."
26
- )
27
-
28
- replica_group
22
+ def replica_connection
23
+ raise NotImplementedError
29
24
  end
30
25
 
31
- def replica_connection
26
+ def put_aside!
27
+ raise NotImplementedError
32
28
  end
33
- undef_method :replica_connection
34
29
 
35
30
  def clear_all_connections!
31
+ raise NotImplementedError
36
32
  end
37
- undef_method :clear_all_connections!
38
33
 
39
- def put_aside!
34
+ def recovery?
35
+ raise NotImplementedError
40
36
  end
41
- undef_method :put_aside!
42
37
 
43
- def recovery?
38
+ def replica_group
39
+ FreshConnection::Deprecation.warn(replica_group: :spec_name)
40
+ spec_name
41
+ end
42
+
43
+ def slave_group
44
+ FreshConnection::Deprecation.warn(slave_group: :spec_name)
45
+ spec_name
44
46
  end
45
- undef_method :recovery?
46
47
  end
47
48
  end
48
49
 
@@ -22,7 +22,12 @@ module FreshConnection
22
22
  return @catch_exceptions if defined?(@catch_exceptions)
23
23
  @catch_exceptions = [ActiveRecord::StatementInvalid]
24
24
  @catch_exceptions << ::Mysql2::Error if defined?(::Mysql2)
25
- @catch_exceptions += [::PG::Error, ::PGError] if defined?(::PG)
25
+
26
+ if defined?(::PG)
27
+ @catch_exceptions << ::PG::Error
28
+ @catch_exceptions << ::PGError if defined?(::PGError)
29
+ end
30
+
26
31
  @catch_exceptions
27
32
  end
28
33
 
@@ -1,73 +1,24 @@
1
1
  require 'active_support/deprecation'
2
- require 'active_support/core_ext/hash/keys'
3
- require 'active_support/hash_with_indifferent_access'
4
- require 'active_support/core_ext/hash/indifferent_access'
2
+ require 'fresh_connection/connection_specification'
5
3
 
6
4
  module FreshConnection
7
5
  class ConnectionFactory
8
6
  def initialize(group, modify_spec = nil)
9
- @group = group.to_sym
10
- @modify_spec = modify_spec || {}.with_indifferent_access
11
- @spec = nil
7
+ deprecation_warn
8
+ @spec = FreshConnection::ConnectionSpecification.new(group, modify_spec: modify_spec)
12
9
  end
13
10
 
14
11
  def new_connection
15
- ActiveRecord::Base.__send__(adapter_method, spec)
12
+ deprecation_warn
13
+ ActiveRecord::Base.__send__(@spec.adapter_method, @spec.confg)
16
14
  end
17
15
 
18
16
  private
19
17
 
20
- def adapter_method
21
- @adapter_method ||= ar_spec.adapter_method
22
- end
23
-
24
- def spec
25
- @spec ||= build_spec
26
- end
27
-
28
- # when building a spec from envars, there may be no database.yml file, so
29
- # be careful to avoid implicit dependency on it or derived contents.
30
-
31
- def build_spec
32
- url = database_group_url(@group.to_s)
33
- if url
34
- build_group_spec_from_url(url)
35
- else
36
- build_spec_from_config
37
- end
38
- end
39
-
40
- def database_group_url(group)
41
- ENV['DATABASE_' + group.upcase + '_URL']
42
- end
43
-
44
- def build_group_spec_from_url(url)
45
- config = ar_spec.config.with_indifferent_access
46
- spec = build_spec_from_url(url)
47
- group_config = (config[@group] ||= {}.with_indifferent_access)
48
- config.merge(group_config).merge(spec).merge(@modify_spec)
49
- end
50
-
51
- def build_spec_from_url(url)
52
- ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(url).to_hash
53
- end
54
-
55
- def build_spec_from_config
56
- config = ar_spec.config.with_indifferent_access
57
- group_config = config[@group] || {}.with_indifferent_access
58
-
59
- if group_config.size == 0 && @group == :replica && config.key?(:slave)
60
- # provide backward-compatibility with :slave profile
61
- ActiveSupport::Deprecation.warn(
62
- "'slave' in database.yml is deprecated and will ignored from version 2.4.0. use 'replica' instead."
63
- )
64
- group_config = (config[:slave] || {}).with_indifferent_access
65
- end
66
- config.merge(group_config).merge(@modify_spec)
67
- end
68
-
69
- def ar_spec
70
- ActiveRecord::Base.connection_pool.spec
18
+ def deprecation_warn
19
+ ActiveSupport::Deprecation.warn(
20
+ "`FreshConnection::ConnectionFactory` class is deprecated and will removed from version 2.5.0."
21
+ )
71
22
  end
72
23
  end
73
24
  end
@@ -1,31 +1,32 @@
1
- require 'concurrent'
2
1
  require 'fresh_connection/abstract_connection_manager'
3
- require 'fresh_connection/connection_factory'
2
+ require 'fresh_connection/connection_specification'
4
3
 
5
4
  module FreshConnection
6
5
  class ConnectionManager < AbstractConnectionManager
7
6
  def initialize(*args)
8
7
  super
9
- @connections = Concurrent::Map.new
8
+
9
+ spec = FreshConnection::ConnectionSpecification.new(spec_name).spec
10
+ @pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
10
11
  end
11
12
 
12
13
  def replica_connection
13
- @connections.fetch_or_store(current_thread_id) do |_|
14
- connection_factory.new_connection
15
- end
14
+ @pool.connection
16
15
  end
17
16
 
18
17
  def put_aside!
19
- conn = @connections.delete(current_thread_id)
20
- return unless conn
21
- conn && conn.disconnect! rescue nil
18
+ return unless @pool.active_connection?
19
+
20
+ conn = replica_connection
21
+ return if conn.transaction_open?
22
+
23
+ @pool.release_connection
24
+ @pool.remove(conn)
25
+ conn.disconnect!
22
26
  end
23
27
 
24
28
  def clear_all_connections!
25
- @connections.each_value do |conn|
26
- conn.disconnect! rescue nil
27
- end
28
- @connections.clear
29
+ @pool.disconnect!
29
30
  end
30
31
 
31
32
  def recovery?
@@ -33,15 +34,5 @@ module FreshConnection
33
34
  put_aside!
34
35
  true
35
36
  end
36
-
37
- private
38
-
39
- def connection_factory
40
- @connection_factory ||= ConnectionFactory.new(@replica_group)
41
- end
42
-
43
- def current_thread_id
44
- Thread.current.object_id
45
- end
46
37
  end
47
38
  end
@@ -0,0 +1,64 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+
4
+ module FreshConnection
5
+ class ConnectionSpecification
6
+ def initialize(spec_name, modify_spec: nil)
7
+ @spec_name = spec_name.to_s
8
+ @modify_spec = modify_spec.with_indifferent_access if modify_spec
9
+ end
10
+
11
+ def spec
12
+ resolver.spec(@spec_name.to_sym)
13
+ end
14
+
15
+ private
16
+
17
+ def resolver
18
+ ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(@spec_name => build_config)
19
+ end
20
+
21
+ # when building a spec from envars, there may be no database.yml file, so
22
+ # be careful to avoid implicit dependency on it or derived contents.
23
+
24
+ def build_config
25
+ config = base_config.with_indifferent_access
26
+
27
+ s_config = replica_config(config)
28
+ config = config.merge(s_config) if s_config
29
+
30
+ config = config.merge(@modify_spec) if defined?(@modify_spec)
31
+ config
32
+ end
33
+
34
+ def replica_config(config)
35
+ if database_group_url
36
+ config_from_url
37
+ else
38
+ c = config[@spec_name]
39
+
40
+ if !c && @spec_name == "replica" && config.key?("slave")
41
+ # provide backward-compatibility with :slave profile
42
+ ActiveSupport::Deprecation.warn(
43
+ "'slave' in database.yml is deprecated and will ignored from version 2.5.0. use 'replica' instead."
44
+ )
45
+ c = config["slave"]
46
+ end
47
+
48
+ c
49
+ end
50
+ end
51
+
52
+ def config_from_url
53
+ ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(database_group_url).to_hash
54
+ end
55
+
56
+ def base_config
57
+ ActiveRecord::Base.connection_pool.spec.config
58
+ end
59
+
60
+ def database_group_url
61
+ ENV["DATABASE_#{@spec_name.upcase}_URL"]
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_support/deprecation'
2
+
3
+ module FreshConnection
4
+ class Deprecation
5
+ class << self
6
+ def warn(list = {})
7
+ list.each do |new_method, old_method|
8
+ ActiveSupport::Deprecation.warn(
9
+ "'#{old_method}' is deprecated and will removed from version 2.5.0. use '#{new_method}' instead."
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module FreshConnection
2
+ class ExecutorHook
3
+ class << self
4
+ def run
5
+ end
6
+
7
+ def complete(*args)
8
+ ReplicaConnectionHandler.instance.put_aside!
9
+ end
10
+
11
+ def install_executor_hooks
12
+ ActiveSupport::Executor.register_hook(self)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,12 +2,11 @@ module FreshConnection
2
2
  module Extend
3
3
  module ArAbstractAdapter
4
4
  def self.prepended(base)
5
- base.send :attr_writer, :replica_group
6
- base.send :attr_accessor, :master_connection
5
+ base.send :attr_accessor, :replica_spec_name, :master_connection
7
6
  end
8
7
 
9
8
  def log(*args)
10
- args[1] = "[#{@replica_group}] #{args[1]}" if defined?(@replica_group)
9
+ args[1] = "[#{@replica_spec_name}] #{args[1]}" if defined?(@replica_spec_name)
11
10
  super
12
11
  end
13
12
 
@@ -1,17 +1,36 @@
1
- require 'active_support/deprecation'
1
+ require 'fresh_connection/deprecation'
2
2
  require 'fresh_connection/access_control'
3
3
  require 'fresh_connection/replica_connection_handler'
4
4
 
5
5
  module FreshConnection
6
6
  module Extend
7
7
  module ArBase
8
+ def replica_connection_specification_name
9
+ if defined?(@replica_connection_specification_name)
10
+ return @replica_connection_specification_name
11
+ end
12
+
13
+ if self == ActiveRecord::Base
14
+ "replica"
15
+ else
16
+ superclass.replica_connection_specification_name
17
+ end
18
+ end
19
+
20
+ def replica_connection_specification_name=(spec_name)
21
+ spec_name = spec_name.to_s
22
+ spec_name = "replica" if spec_name.empty? || spec_name == "slave"
23
+
24
+ @replica_connection_specification_name = spec_name
25
+ end
26
+
8
27
  def connection
9
28
  master_c = super
10
29
  return master_c unless FreshConnection::AccessControl.replica_access?
11
30
 
12
31
  replica_c = replica_connection
13
32
  replica_c.master_connection = master_c
14
- replica_c.replica_group = replica_group if logger && logger.debug?
33
+ replica_c.replica_spec_name = replica_connection_specification_name if logger && logger.debug?
15
34
  replica_c
16
35
  end
17
36
 
@@ -23,34 +42,19 @@ module FreshConnection
23
42
  all.manage_access(false, &block)
24
43
  end
25
44
 
26
- def establish_fresh_connection(replica_group = "replica")
27
- replica_connection_handler.establish_connection(name, replica_group)
45
+ def establish_fresh_connection(spec_name = "replica")
46
+ self.replica_connection_specification_name = spec_name
47
+ replica_connection_handler.establish_connection(replica_connection_specification_name)
28
48
  end
29
49
 
30
50
  def replica_connection
31
- replica_connection_handler.connection(self)
32
- end
33
-
34
- def slave_connection
35
- ActiveSupport::Deprecation.warn(
36
- "'slave_connection' is deprecated and will removed from version 2.4.0. use 'replica_connection' instead."
37
- )
38
-
39
- replica_connection
51
+ replica_connection_handler.connection(replica_connection_specification_name)
40
52
  end
41
53
 
42
54
  def clear_all_replica_connections!
43
55
  replica_connection_handler.clear_all_connections!
44
56
  end
45
57
 
46
- def clear_all_slave_connections!
47
- ActiveSupport::Deprecation.warn(
48
- "'clear_all_slave_connections!' is deprecated and will removed from version 2.4.0. use 'clear_all_replica_connections!' instead."
49
- )
50
-
51
- clear_all_replica_connections!
52
- end
53
-
54
58
  def master_db_only!
55
59
  @_fresh_connection_master_only = true
56
60
  end
@@ -64,42 +68,44 @@ module FreshConnection
64
68
  replica_connection_handler.put_aside!
65
69
  end
66
70
 
67
- def slave_connection_put_aside!
68
- ActiveSupport::Deprecation.warn(
69
- "'slave_connection_put_aside!' is deprecated and will removed from version 2.4.0. use 'replica_connection_put_aside!' instead."
70
- )
71
+ def replica_connection_recovery?
72
+ replica_connection_handler.recovery?(replica_connection_specification_name)
73
+ end
71
74
 
72
- replica_connection_put_aside!
75
+ def slave_connection
76
+ FreshConnection::Deprecation.warn(slave_connection: :replica_connection)
77
+ replica_connection
73
78
  end
74
79
 
75
- def replica_connection_recovery?
76
- replica_connection_handler.recovery?(self)
80
+ def clear_all_slave_connections
81
+ FreshConnection::Deprecation.warn(clear_all_slave_connections!: :clear_all_replica_connections!)
82
+ clear_all_replica_connections!
77
83
  end
78
84
 
79
- def slave_connection_recovery?
80
- ActiveSupport::Deprecation.warn(
81
- "'slave_connection_recovery?' is deprecated and will removed from version 2.4.0. use 'replica_connection_recovery?' instead."
82
- )
85
+ def slave_connection_put_aside!
86
+ FreshConnection::Deprecation.warn(slave_connection_put_aside!: :replica_connection_put_aside!)
87
+ replica_connection_put_aside!
88
+ end
83
89
 
90
+ def slave_connection_recovery?
91
+ FreshConnection::Deprecation.warn(slave_connection_recovery?: :replica_connection_recovery?)
84
92
  replica_connection_recovery?
85
93
  end
86
94
 
87
95
  def replica_group
88
- replica_connection_handler.replica_group(self)
96
+ FreshConnection::Deprecation.warn(replica_group: :replica_connection_specification_name)
97
+ replica_connection_specification_name
89
98
  end
90
99
 
91
100
  def slave_group
92
- ActiveSupport::Deprecation.warn(
93
- "'slave_connection_recovery?' is deprecated and will removed from version 2.4.0. use 'replica_connection_recovery?' instead."
94
- )
95
-
96
- replica_group
101
+ FreshConnection::Deprecation.warn(slave_group: :replica_connection_specification_name)
102
+ replica_connection_specification_name
97
103
  end
98
104
 
99
105
  private
100
106
 
101
107
  def replica_connection_handler
102
- @@replica_connection_handler ||= FreshConnection::ReplicaConnectionHandler.new
108
+ FreshConnection::ReplicaConnectionHandler.instance
103
109
  end
104
110
  end
105
111
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/deprecation'
1
+ require 'fresh_connection/deprecation'
2
2
 
3
3
  module FreshConnection
4
4
  module Extend
@@ -59,10 +59,7 @@ module FreshConnection
59
59
  end
60
60
 
61
61
  def enable_slave_access
62
- ActiveSupport::Deprecation.warn(
63
- "'enable_slave_access' is deprecated and will removed from version 2.4.0. use 'enable_replica_access' instead."
64
- )
65
-
62
+ FreshConnection::Deprecation.warn(enable_slave_access: :enable_replica_access)
66
63
  enable_replica_access
67
64
  end
68
65
 
@@ -1,20 +1,15 @@
1
- require 'active_record'
2
- require 'fresh_connection/extend/ar_base'
3
- require 'fresh_connection/extend/ar_relation'
4
- require 'fresh_connection/extend/ar_relation_merger'
5
- require 'fresh_connection/extend/ar_abstract_adapter'
6
-
7
- module ActiveRecord
8
- Base.extend FreshConnection::Extend::ArBase
9
- Relation.send :prepend, FreshConnection::Extend::ArRelation
10
- Relation::Merger.send :prepend, FreshConnection::Extend::ArRelationMerger
11
-
12
- if defined?(StatementCache)
13
- require 'fresh_connection/extend/ar_statement_cache'
14
- StatementCache.send :prepend, FreshConnection::Extend::ArStatementCache
15
- end
16
-
17
- ConnectionAdapters::AbstractAdapter.send :prepend, FreshConnection::Extend::ArAbstractAdapter
18
-
19
- Base.establish_fresh_connection
1
+ require 'active_support'
2
+
3
+ ActiveSupport.on_load(:active_record) do
4
+ require 'fresh_connection/extend/ar_base'
5
+ require 'fresh_connection/extend/ar_relation'
6
+ require 'fresh_connection/extend/ar_relation_merger'
7
+ require 'fresh_connection/extend/ar_statement_cache'
8
+ require 'fresh_connection/extend/ar_abstract_adapter'
9
+
10
+ ActiveRecord::Base.extend FreshConnection::Extend::ArBase
11
+ ActiveRecord::Relation.send :prepend, FreshConnection::Extend::ArRelation
12
+ ActiveRecord::Relation::Merger.send :prepend, FreshConnection::Extend::ArRelationMerger
13
+ ActiveRecord::StatementCache.send :prepend, FreshConnection::Extend::ArStatementCache
14
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.send :prepend, FreshConnection::Extend::ArAbstractAdapter
20
15
  end
@@ -1,18 +1,16 @@
1
- require 'fresh_connection/rack/connection_management'
1
+ require 'fresh_connection/executor_hook'
2
2
 
3
3
  module FreshConnection
4
4
  class Railtie < Rails::Railtie
5
5
  initializer "fresh_connection.configure_rails_initialization" do |app|
6
- if defined?(ActiveRecord::ConnectionAdapters::ConnectionManagement)
7
- app.config.app_middleware.insert_before(
8
- ActiveRecord::ConnectionAdapters::ConnectionManagement,
9
- FreshConnection::Rack::ConnectionManagement
10
- )
11
- else
12
- app.config.app_middleware.insert_before(
13
- ActionDispatch::Executor,
14
- FreshConnection::Rack::ConnectionManagement
15
- )
6
+ ActiveSupport.on_load(:active_record) do
7
+ FreshConnection::ExecutorHook.install_executor_hooks
8
+ end
9
+ end
10
+
11
+ initializer "fresh_connection.initialize_database", after: "active_record.initialize_database" do
12
+ ActiveSupport.on_load(:active_record) do
13
+ ActiveRecord::Base.establish_fresh_connection
16
14
  end
17
15
  end
18
16
  end
@@ -0,0 +1,12 @@
1
+ require 'fresh_connection/rack/connection_management'
2
+
3
+ module FreshConnection
4
+ class Railtie < Rails::Railtie
5
+ initializer "fresh_connection.configure_rails_initialization" do |app|
6
+ app.config.app_middleware.insert_before(
7
+ ActiveRecord::ConnectionAdapters::ConnectionManagement,
8
+ FreshConnection::Rack::ConnectionManagement
9
+ )
10
+ end
11
+ end
12
+ end
@@ -1,23 +1,33 @@
1
1
  require 'concurrent'
2
+ require 'singleton'
2
3
 
3
4
  module FreshConnection
4
5
  class ReplicaConnectionHandler
6
+ include Singleton
7
+
5
8
  def initialize
6
- @replica_group_to_pool = Concurrent::Map.new
7
- @class_to_pool = Concurrent::Map.new
9
+ @owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
10
+ h[k] = Concurrent::Map.new(initial_capacity: 2)
11
+ end
8
12
  end
9
13
 
10
- def establish_connection(name, replica_group)
11
- if cm = @class_to_pool[name]
12
- cm.put_aside!
13
- @class_to_pool.delete(name)
14
- end
14
+ def establish_connection(spec_name)
15
+ spec_name = spec_name.to_s
16
+ remove_connection(spec_name)
15
17
 
16
- @replica_group_to_pool[name] = replica_group
18
+ message_bus = ActiveSupport::Notifications.instrumenter
19
+ payload = {
20
+ connection_id: object_id,
21
+ spec_name: spec_name
22
+ }
23
+
24
+ message_bus.instrument("!connection.active_record", payload) do
25
+ owner_to_pool[spec_name] = FreshConnection.connection_manager.new(spec_name)
26
+ end
17
27
  end
18
28
 
19
- def connection(klass)
20
- detect_connection_manager(klass).replica_connection
29
+ def connection(spec_name)
30
+ detect_connection_manager(spec_name).replica_connection
21
31
  end
22
32
 
23
33
  def clear_all_connections!
@@ -26,8 +36,8 @@ module FreshConnection
26
36
  end
27
37
  end
28
38
 
29
- def recovery?(klass)
30
- detect_connection_manager(klass).recovery?
39
+ def recovery?(spec_name)
40
+ detect_connection_manager(spec_name).recovery?
31
41
  end
32
42
 
33
43
  def put_aside!
@@ -36,30 +46,27 @@ module FreshConnection
36
46
  end
37
47
  end
38
48
 
39
- def replica_group(klass)
40
- detect_connection_manager(klass).replica_group
41
- end
42
-
43
49
  private
44
50
 
51
+ def remove_connection(spec_name)
52
+ pool = owner_to_pool.delete(spec_name.to_s)
53
+ return unless pool
54
+
55
+ pool.clear_all_connections!
56
+ end
57
+
45
58
  def all_connection_managers
46
- @class_to_pool.each_value do |connection_manager|
59
+ owner_to_pool.each_value do |connection_manager|
47
60
  yield(connection_manager)
48
61
  end
49
62
  end
50
63
 
51
- def detect_connection_manager(klass)
52
- c = class_to_pool(klass.name)
53
- return c if c
54
- return nil if ActiveRecord::Base == klass
55
- detect_connection_manager(klass.superclass)
64
+ def detect_connection_manager(spec_name)
65
+ owner_to_pool[spec_name.to_s]
56
66
  end
57
67
 
58
- def class_to_pool(name)
59
- return @class_to_pool[name] if @class_to_pool.key?(name)
60
- g = @replica_group_to_pool[name]
61
- return nil unless g
62
- @class_to_pool[name] = FreshConnection.connection_manager.new(g)
68
+ def owner_to_pool
69
+ @owner_to_pool[Process.pid]
63
70
  end
64
71
  end
65
72
  end
@@ -1,4 +1,4 @@
1
1
  module FreshConnection
2
- VERSION = "2.3.2"
2
+ VERSION = "2.4.0.rc1"
3
3
  end
4
4
 
@@ -15,4 +15,11 @@ module FreshConnection
15
15
  end
16
16
 
17
17
  require 'fresh_connection/extend'
18
- require 'fresh_connection/railtie' if defined?(Rails)
18
+
19
+ if defined?(Rails)
20
+ if Rails::VERSION::MAJOR == "4"
21
+ require 'fresh_connection/railtie_for_rails4'
22
+ else
23
+ require 'fresh_connection/railtie'
24
+ end
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fresh_connection
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsukasa OISHI
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-27 00:00:00.000000000 Z
11
+ date: 2017-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 4.2.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.1'
22
+ version: '5.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 4.2.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.1'
32
+ version: '5.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: 4.2.0
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '5.1'
42
+ version: '5.2'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: 4.2.0
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '5.1'
52
+ version: '5.2'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: concurrent-ruby
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -210,11 +210,15 @@ files:
210
210
  - fresh_connection.gemspec
211
211
  - gemfiles/rails42.gemfile
212
212
  - gemfiles/rails50.gemfile
213
+ - gemfiles/rails51.gemfile
213
214
  - lib/fresh_connection.rb
214
215
  - lib/fresh_connection/abstract_connection_manager.rb
215
216
  - lib/fresh_connection/access_control.rb
216
217
  - lib/fresh_connection/connection_factory.rb
217
218
  - lib/fresh_connection/connection_manager.rb
219
+ - lib/fresh_connection/connection_specification.rb
220
+ - lib/fresh_connection/deprecation.rb
221
+ - lib/fresh_connection/executor_hook.rb
218
222
  - lib/fresh_connection/extend.rb
219
223
  - lib/fresh_connection/extend/ar_abstract_adapter.rb
220
224
  - lib/fresh_connection/extend/ar_base.rb
@@ -223,6 +227,7 @@ files:
223
227
  - lib/fresh_connection/extend/ar_statement_cache.rb
224
228
  - lib/fresh_connection/rack/connection_management.rb
225
229
  - lib/fresh_connection/railtie.rb
230
+ - lib/fresh_connection/railtie_for_rails4.rb
226
231
  - lib/fresh_connection/replica_connection_handler.rb
227
232
  - lib/fresh_connection/version.rb
228
233
  - log/.gitkeep
@@ -238,15 +243,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
243
  requirements:
239
244
  - - ">="
240
245
  - !ruby/object:Gem::Version
241
- version: '2.1'
246
+ version: '2.2'
242
247
  required_rubygems_version: !ruby/object:Gem::Requirement
243
248
  requirements:
244
- - - ">="
249
+ - - ">"
245
250
  - !ruby/object:Gem::Version
246
- version: '0'
251
+ version: 1.3.1
247
252
  requirements: []
248
253
  rubyforge_project:
249
- rubygems_version: 2.4.5.1
254
+ rubygems_version: 2.5.2
250
255
  signing_key:
251
256
  specification_version: 4
252
257
  summary: FreshConnection supports connections with configured replica servers.