fresh_connection 3.0.0.rc1 → 3.0.0.rc2
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 +4 -4
- data/Appraisals +3 -4
- data/gemfiles/rails52.gemfile +3 -3
- data/lib/fresh_connection/access_control.rb +41 -20
- data/lib/fresh_connection/check_adapter.rb +21 -15
- data/lib/fresh_connection/extend/adapters/m2_adapter.rb +0 -8
- data/lib/fresh_connection/extend/adapters/pg_adapter.rb +0 -16
- data/lib/fresh_connection/extend/ar_abstract_adapter.rb +15 -5
- data/lib/fresh_connection/extend/ar_base.rb +28 -38
- data/lib/fresh_connection/extend/ar_relation.rb +10 -23
- data/lib/fresh_connection/extend/ar_statement_cache.rb +1 -1
- data/lib/fresh_connection/replica_connection_handler.rb +0 -1
- data/lib/fresh_connection/version.rb +1 -1
- data/lib/fresh_connection.rb +4 -0
- metadata +3 -4
- data/lib/fresh_connection/rack/connection_management.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9647d59e3a6fcfa7c194109a6797bc0962f42a491ff226bbe140a093a3c71c28
|
4
|
+
data.tar.gz: 133f4e76f9e4f369b69241e18e331f503b2e00bc337c7778f3c026aee8a08796
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5a063f3414c1e2251410930a06e09966af1db29920ec46d25908465dfef59c43feaf458aa3d71e6e04e82d343b2bca5f5caeb54a05be5947cd6800330a5ab12
|
7
|
+
data.tar.gz: 6d626b364389c7d63b687e1a6b6d2c551d1f66f73d32b782bb43505f5e44cec268d87779234c56929d678375cd929ca5ac13ed48557c12515e55e35c2097a1f9
|
data/Appraisals
CHANGED
@@ -13,9 +13,8 @@ appraise "rails51" do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
appraise "rails52" do
|
16
|
-
gem 'activerecord', '5.2.0
|
17
|
-
gem 'activesupport', '5.2.0
|
18
|
-
|
19
|
-
gem 'mysql2', '~> 0.4.4'
|
16
|
+
gem 'activerecord', '5.2.0'
|
17
|
+
gem 'activesupport', '5.2.0'
|
18
|
+
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
20
19
|
gem 'pg', '>= 0.18', '< 2.0'
|
21
20
|
end
|
data/gemfiles/rails52.gemfile
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "5.2.0
|
6
|
-
gem "activesupport", "5.2.0
|
7
|
-
gem "mysql2", "
|
5
|
+
gem "activerecord", "5.2.0"
|
6
|
+
gem "activesupport", "5.2.0"
|
7
|
+
gem "mysql2", ">= 0.4.4", "< 0.6.0"
|
8
8
|
gem "pg", ">= 0.18", "< 2.0"
|
9
9
|
|
10
10
|
gemspec path: "../"
|
@@ -3,16 +3,22 @@
|
|
3
3
|
module FreshConnection
|
4
4
|
class AccessControl
|
5
5
|
class << self
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
RETRY_LIMIT = 3
|
7
|
+
private_constant :RETRY_LIMIT
|
8
|
+
|
9
|
+
def manage_access(model:, replica_access:, &block)
|
10
|
+
return force_master_access(&block) if model.master_db_only?
|
11
|
+
|
12
|
+
retry_count = 0
|
13
|
+
begin
|
14
|
+
access(replica_access, &block)
|
15
|
+
rescue *catch_exceptions
|
16
|
+
if recovery?(model.replica_spec_name)
|
17
|
+
retry_count += 1
|
18
|
+
retry if retry_count < RETRY_LIMIT
|
19
|
+
end
|
9
20
|
|
10
|
-
|
11
|
-
if access_db
|
12
|
-
block.call
|
13
|
-
else
|
14
|
-
db = enable_replica_access ? :replica : :master
|
15
|
-
switch_to(db, &block)
|
21
|
+
raise
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
@@ -20,20 +26,18 @@ module FreshConnection
|
|
20
26
|
access_db == :replica
|
21
27
|
end
|
22
28
|
|
23
|
-
|
24
|
-
return @catch_exceptions if defined?(@catch_exceptions)
|
25
|
-
@catch_exceptions = [ActiveRecord::StatementInvalid]
|
26
|
-
@catch_exceptions << ::Mysql2::Error if defined?(::Mysql2)
|
27
|
-
|
28
|
-
if defined?(::PG)
|
29
|
-
@catch_exceptions << ::PG::Error
|
30
|
-
@catch_exceptions << ::PGError if defined?(::PGError)
|
31
|
-
end
|
29
|
+
private
|
32
30
|
|
33
|
-
|
31
|
+
def force_master_access(&block)
|
32
|
+
switch_to(:master, &block)
|
34
33
|
end
|
35
34
|
|
36
|
-
|
35
|
+
def access(replica_access, &block)
|
36
|
+
return yield if access_db
|
37
|
+
|
38
|
+
db = replica_access ? :replica : :master
|
39
|
+
switch_to(db, &block)
|
40
|
+
end
|
37
41
|
|
38
42
|
def switch_to(new_db)
|
39
43
|
old_db = access_db
|
@@ -50,6 +54,23 @@ module FreshConnection
|
|
50
54
|
def access_to(db)
|
51
55
|
Thread.current[:fresh_connection_access_target] = db
|
52
56
|
end
|
57
|
+
|
58
|
+
def recovery?(spec_name)
|
59
|
+
FreshConnection::ReplicaConnectionHandler.instance.recovery?(spec_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def catch_exceptions
|
63
|
+
return @catch_exceptions if defined?(@catch_exceptions)
|
64
|
+
@catch_exceptions = [ActiveRecord::StatementInvalid]
|
65
|
+
@catch_exceptions << ::Mysql2::Error if defined?(::Mysql2)
|
66
|
+
|
67
|
+
if defined?(::PG)
|
68
|
+
@catch_exceptions << ::PG::Error
|
69
|
+
@catch_exceptions << ::PGError if defined?(::PGError)
|
70
|
+
end
|
71
|
+
|
72
|
+
@catch_exceptions
|
73
|
+
end
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
@@ -2,24 +2,30 @@
|
|
2
2
|
|
3
3
|
module FreshConnection
|
4
4
|
module CheckAdapter
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class << self
|
6
|
+
def check(klass)
|
7
|
+
if mysql?(klass)
|
8
|
+
:mysql
|
9
|
+
elsif postgresql?(klass)
|
10
|
+
:postgresql
|
11
|
+
end
|
12
12
|
end
|
13
|
-
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def mysql?(klass)
|
15
|
+
if defined?(::ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
16
|
+
klass == ::ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
17
|
+
else
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
def postgresql?(klass)
|
23
|
+
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
24
|
+
klass == ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -3,22 +3,6 @@
|
|
3
3
|
module FreshConnection
|
4
4
|
module Extend
|
5
5
|
module PgAdapter
|
6
|
-
def select_all(*args)
|
7
|
-
change_connection { super }
|
8
|
-
end
|
9
|
-
|
10
|
-
def select_rows(*args)
|
11
|
-
change_connection { super }
|
12
|
-
end
|
13
|
-
|
14
|
-
def select_values(*args)
|
15
|
-
change_connection { super }
|
16
|
-
end
|
17
|
-
|
18
|
-
def select_value(*args)
|
19
|
-
change_connection { super }
|
20
|
-
end
|
21
|
-
|
22
6
|
private
|
23
7
|
|
24
8
|
def change_connection
|
@@ -5,13 +5,13 @@ module FreshConnection
|
|
5
5
|
module Extend
|
6
6
|
module ArAbstractAdapter
|
7
7
|
def inherited(klass)
|
8
|
-
klass.prepend BaseAdapter
|
9
|
-
|
10
8
|
case FreshConnection::CheckAdapter.check(klass)
|
11
9
|
when :mysql
|
10
|
+
klass.prepend BaseAdapter
|
12
11
|
require 'fresh_connection/extend/adapters/m2_adapter'
|
13
12
|
klass.prepend M2Adapter
|
14
13
|
when :postgresql
|
14
|
+
klass.prepend BaseAdapter
|
15
15
|
require 'fresh_connection/extend/adapters/pg_adapter'
|
16
16
|
klass.prepend PgAdapter
|
17
17
|
end
|
@@ -24,13 +24,23 @@ module FreshConnection
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def log(*args)
|
27
|
-
args[1] = "[#{
|
27
|
+
args[1] = "[#{__replica_spec_name}] #{args[1]}" if __replica_spec_name
|
28
28
|
super
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def select_all(*args)
|
32
|
+
change_connection { super }
|
33
|
+
end
|
34
|
+
|
35
|
+
def select_value(*args)
|
36
|
+
change_connection { super }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def __replica_spec_name
|
32
42
|
return nil if !defined?(@model_class) || !@model_class
|
33
|
-
@model_class.
|
43
|
+
@model_class.replica_spec_name
|
34
44
|
end
|
35
45
|
end
|
36
46
|
end
|
@@ -5,50 +5,36 @@ require 'fresh_connection/replica_connection_handler'
|
|
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?
|
23
|
-
|
24
|
-
@replica_connection_specification_name = spec_name
|
25
|
-
end
|
26
|
-
|
27
|
-
def connection
|
28
|
-
c = super
|
29
|
-
c.model_class = self
|
30
|
-
c
|
31
|
-
end
|
32
|
-
|
33
8
|
def read_master
|
34
9
|
all.read_master
|
35
10
|
end
|
36
11
|
|
37
12
|
def with_master(&block)
|
38
|
-
|
13
|
+
FreshConnection::AccessControl.manage_access(
|
14
|
+
model: self,
|
15
|
+
replica_access: false,
|
16
|
+
&block
|
17
|
+
)
|
39
18
|
end
|
40
19
|
|
41
|
-
def
|
42
|
-
|
43
|
-
replica_connection_handler.establish_connection(replica_connection_specification_name)
|
20
|
+
def connection
|
21
|
+
super.tap {|c| c.model_class = self }
|
44
22
|
end
|
45
23
|
|
46
24
|
def replica_connection
|
47
|
-
|
25
|
+
__replica_handler.connection(replica_spec_name)
|
48
26
|
end
|
49
27
|
|
50
28
|
def clear_all_replica_connections!
|
51
|
-
|
29
|
+
__replica_handler.clear_all_connections!
|
30
|
+
end
|
31
|
+
|
32
|
+
def establish_fresh_connection(spec_name = nil)
|
33
|
+
spec_name = spec_name.to_s
|
34
|
+
spec_name = "replica" if spec_name.empty?
|
35
|
+
@_replica_spec_name = spec_name
|
36
|
+
|
37
|
+
__replica_handler.establish_connection(replica_spec_name)
|
52
38
|
end
|
53
39
|
|
54
40
|
def master_db_only!
|
@@ -60,17 +46,21 @@ module FreshConnection
|
|
60
46
|
(self != ActiveRecord::Base && superclass.master_db_only?)
|
61
47
|
end
|
62
48
|
|
63
|
-
def
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
def replica_connection_recovery?
|
68
|
-
replica_connection_handler.recovery?(replica_connection_specification_name)
|
49
|
+
def replica_spec_name
|
50
|
+
@_replica_spec_name ||= __search_replica_spec_name
|
69
51
|
end
|
70
52
|
|
71
53
|
private
|
72
54
|
|
73
|
-
def
|
55
|
+
def __search_replica_spec_name
|
56
|
+
if self == ActiveRecord::Base
|
57
|
+
"replica"
|
58
|
+
else
|
59
|
+
superclass.replica_spec_name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def __replica_handler
|
74
64
|
FreshConnection::ReplicaConnectionHandler.instance
|
75
65
|
end
|
76
66
|
end
|
@@ -3,27 +3,6 @@
|
|
3
3
|
module FreshConnection
|
4
4
|
module Extend
|
5
5
|
module ArRelation
|
6
|
-
RETRY_LIMIT = 3
|
7
|
-
private_constant :RETRY_LIMIT
|
8
|
-
|
9
|
-
def manage_access(replica_access = enable_replica_access, &block)
|
10
|
-
if @klass.master_db_only?
|
11
|
-
FreshConnection::AccessControl.force_master_access(&block)
|
12
|
-
else
|
13
|
-
retry_count = 0
|
14
|
-
begin
|
15
|
-
FreshConnection::AccessControl.access(replica_access, &block)
|
16
|
-
rescue *FreshConnection::AccessControl.catch_exceptions
|
17
|
-
if @klass.replica_connection_recovery?
|
18
|
-
retry_count += 1
|
19
|
-
retry if retry_count < RETRY_LIMIT
|
20
|
-
end
|
21
|
-
|
22
|
-
raise
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
6
|
def calculate(*args)
|
28
7
|
manage_access { super }
|
29
8
|
end
|
@@ -54,8 +33,12 @@ module FreshConnection
|
|
54
33
|
@values[:read_master] = value
|
55
34
|
end
|
56
35
|
|
57
|
-
def enable_replica_access
|
58
|
-
|
36
|
+
def manage_access(replica_access: enable_replica_access, &block)
|
37
|
+
FreshConnection::AccessControl.manage_access(
|
38
|
+
model: @klass,
|
39
|
+
replica_access: replica_access,
|
40
|
+
&block
|
41
|
+
)
|
59
42
|
end
|
60
43
|
|
61
44
|
private
|
@@ -63,6 +46,10 @@ module FreshConnection
|
|
63
46
|
def exec_queries
|
64
47
|
manage_access { super }
|
65
48
|
end
|
49
|
+
|
50
|
+
def enable_replica_access
|
51
|
+
connection.open_transactions.zero? && !read_master_value
|
52
|
+
end
|
66
53
|
end
|
67
54
|
end
|
68
55
|
end
|
data/lib/fresh_connection.rb
CHANGED
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: 3.0.0.
|
4
|
+
version: 3.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tsukasa OISHI
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -232,7 +232,6 @@ files:
|
|
232
232
|
- lib/fresh_connection/extend/ar_relation.rb
|
233
233
|
- lib/fresh_connection/extend/ar_relation_merger.rb
|
234
234
|
- lib/fresh_connection/extend/ar_statement_cache.rb
|
235
|
-
- lib/fresh_connection/rack/connection_management.rb
|
236
235
|
- lib/fresh_connection/railtie.rb
|
237
236
|
- lib/fresh_connection/replica_connection_handler.rb
|
238
237
|
- lib/fresh_connection/version.rb
|
@@ -257,7 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
257
256
|
version: 1.3.1
|
258
257
|
requirements: []
|
259
258
|
rubyforge_project:
|
260
|
-
rubygems_version: 2.7.
|
259
|
+
rubygems_version: 2.7.6
|
261
260
|
signing_key:
|
262
261
|
specification_version: 4
|
263
262
|
summary: FreshConnection supports connections with configured replica servers.
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FreshConnection
|
4
|
-
module Rack
|
5
|
-
class ConnectionManagement
|
6
|
-
def initialize(app)
|
7
|
-
@app = app
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(env)
|
11
|
-
testing = env['rack.test']
|
12
|
-
|
13
|
-
response = @app.call(env)
|
14
|
-
response[2] = ::Rack::BodyProxy.new(response[2]) do
|
15
|
-
ActiveRecord::Base.replica_connection_put_aside! unless testing
|
16
|
-
end
|
17
|
-
|
18
|
-
response
|
19
|
-
rescue Exception
|
20
|
-
ActiveRecord::Base.replica_connection_put_aside! unless testing
|
21
|
-
raise
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|