standby 5.0.0 → 5.1.0
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/.github/workflows/ci.yml +1 -0
- data/Rakefile +1 -1
- data/gemfiles/rails6.1.gemfile +13 -0
- data/lib/standby/active_record/base.rb +10 -0
- data/lib/standby/connection_holder.rb +11 -8
- data/lib/standby/version.rb +1 -1
- data/lib/standby.rb +9 -1
- data/spec/configuration_spec.rb +38 -4
- data/spec/spec_helper.rb +4 -0
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed313fd2c207aef137a574816b7574d6614d5c2446f2d733aa7d08d2a40b6382
|
|
4
|
+
data.tar.gz: cda7f21a3cf9aa71c84da0cf8e985e965bd78fde3a21b5e57a8902a0e4b581a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e9d7d67ea19465e263e36a7c6318e9f4de15b6c9f53dd1a0e51e6782b1118c2c0e3352b213c687b44ffc2da5d87cc5aa9a270b7e3cea2b3f64b86be4d9d74e5
|
|
7
|
+
data.tar.gz: 4d07f9692a78f4777814282ee120d9ac6df6ad0e723555758f1bb29062082158460728579c2666e3def498a8eaead6b29b4bc344beab76c9d50f6f41a62c5856
|
data/.github/workflows/ci.yml
CHANGED
data/Rakefile
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'activerecord', '~> 6.1'
|
|
4
|
+
gem 'sqlite3', '~> 1.4'
|
|
5
|
+
|
|
6
|
+
# Rails 6.1 compat with Ruby 3.4+ (these were removed from default gems)
|
|
7
|
+
gem 'logger'
|
|
8
|
+
gem 'mutex_m'
|
|
9
|
+
gem 'bigdecimal'
|
|
10
|
+
gem 'base64'
|
|
11
|
+
gem 'drb'
|
|
12
|
+
|
|
13
|
+
gemspec name: 'standby', path: '../'
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
module ActiveRecord
|
|
2
2
|
class Base
|
|
3
3
|
class << self
|
|
4
|
+
alias_method :connection_pool_without_standby, :connection_pool
|
|
4
5
|
alias_method :connection_without_standby, :connection
|
|
5
6
|
|
|
7
|
+
def connection_pool
|
|
8
|
+
case Thread.current[:_standby]
|
|
9
|
+
when :primary, NilClass
|
|
10
|
+
connection_pool_without_standby
|
|
11
|
+
else
|
|
12
|
+
Standby.connection_holder(Thread.current[:_standby]).connection_pool_without_standby
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
6
16
|
def connection
|
|
7
17
|
case Thread.current[:_standby]
|
|
8
18
|
when :primary, NilClass
|
|
@@ -6,7 +6,8 @@ module Standby
|
|
|
6
6
|
# for delayed activation
|
|
7
7
|
def activate(target)
|
|
8
8
|
env_name = "#{ActiveRecord::ConnectionHandling::RAILS_ENV.call}_#{target}"
|
|
9
|
-
|
|
9
|
+
# Rails 6.1+ exposes DatabaseConfigurations helpers; older versions still use hash access.
|
|
10
|
+
if ActiveRecord::Base.configurations.respond_to?(:find_db_config)
|
|
10
11
|
spec = ActiveRecord::Base.configurations.find_db_config(env_name)&.configuration_hash
|
|
11
12
|
else
|
|
12
13
|
spec = ActiveRecord::Base.configurations[env_name]
|
|
@@ -21,14 +22,16 @@ module Standby
|
|
|
21
22
|
class << self
|
|
22
23
|
def connection_holder(target)
|
|
23
24
|
klass_name = "Standby#{target.to_s.camelize}ConnectionHolder"
|
|
24
|
-
standby_connections[klass_name]
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
standby_connections[klass_name] || standby_connections_mutex.synchronize do
|
|
26
|
+
standby_connections[klass_name] ||= begin
|
|
27
|
+
klass = Class.new(Standby::ConnectionHolder) do
|
|
28
|
+
self.abstract_class = true
|
|
29
|
+
end
|
|
30
|
+
Object.const_set(klass_name, klass)
|
|
31
|
+
klass.activate(target)
|
|
32
|
+
klass
|
|
27
33
|
end
|
|
28
|
-
Object.const_set(klass_name, klass)
|
|
29
|
-
klass.activate(target)
|
|
30
|
-
klass
|
|
31
34
|
end
|
|
32
35
|
end
|
|
33
36
|
end
|
|
34
|
-
end
|
|
37
|
+
end
|
data/lib/standby/version.rb
CHANGED
data/lib/standby.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'logger'
|
|
1
2
|
require 'active_record'
|
|
2
3
|
require 'standby/version'
|
|
3
4
|
require 'standby/base'
|
|
@@ -10,11 +11,18 @@ require 'standby/active_record/relation'
|
|
|
10
11
|
require 'standby/active_record/log_subscriber'
|
|
11
12
|
|
|
12
13
|
module Standby
|
|
14
|
+
@standby_connections = {}
|
|
15
|
+
@standby_connections_mutex = Mutex.new
|
|
16
|
+
|
|
13
17
|
class << self
|
|
14
18
|
attr_accessor :disabled
|
|
15
19
|
|
|
16
20
|
def standby_connections
|
|
17
|
-
@standby_connections
|
|
21
|
+
@standby_connections
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def standby_connections_mutex
|
|
25
|
+
@standby_connections_mutex
|
|
18
26
|
end
|
|
19
27
|
|
|
20
28
|
def on_standby(name = :null_state, &block)
|
data/spec/configuration_spec.rb
CHANGED
|
@@ -3,8 +3,9 @@ require 'spec_helper'
|
|
|
3
3
|
describe 'configuration' do
|
|
4
4
|
before do
|
|
5
5
|
# Backup connection and configs
|
|
6
|
-
@backup_conn = Standby.instance_variable_get
|
|
7
|
-
|
|
6
|
+
@backup_conn = (Standby.instance_variable_get(:@standby_connections) || {}).dup
|
|
7
|
+
# Rails 6.1+ wraps configurations in ActiveRecord::DatabaseConfigurations.
|
|
8
|
+
if ActiveRecord::Base.configurations.respond_to?(:configs_for)
|
|
8
9
|
@backup_config = ActiveRecord::Base.configurations.configs_for.map do |config|
|
|
9
10
|
[config.env_name, config.configuration_hash]
|
|
10
11
|
end.to_h
|
|
@@ -26,7 +27,8 @@ describe 'configuration' do
|
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
it 'raises error if standby configuration not specified' do
|
|
29
|
-
|
|
30
|
+
# Rails 6.1+ no longer supports mutating configurations via hash-style access.
|
|
31
|
+
if ActiveRecord::Base.configurations.respond_to?(:configs_for)
|
|
30
32
|
ActiveRecord::Base.configurations = @backup_config.merge({ 'test_standby' => {} })
|
|
31
33
|
else
|
|
32
34
|
ActiveRecord::Base.configurations['test_standby'] = nil
|
|
@@ -36,7 +38,8 @@ describe 'configuration' do
|
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
it 'connects to primary if standby configuration is disabled' do
|
|
39
|
-
|
|
41
|
+
# Rails 6.1+ no longer supports mutating configurations via hash-style access.
|
|
42
|
+
if ActiveRecord::Base.configurations.respond_to?(:configs_for)
|
|
40
43
|
ActiveRecord::Base.configurations = @backup_config.merge({ 'test_standby' => {} })
|
|
41
44
|
else
|
|
42
45
|
ActiveRecord::Base.configurations['test_standby'] = nil
|
|
@@ -45,4 +48,35 @@ describe 'configuration' do
|
|
|
45
48
|
|
|
46
49
|
expect(Standby.on_standby { User.count }).to be 2
|
|
47
50
|
end
|
|
51
|
+
|
|
52
|
+
it 'initializes a standby connection holder once under contention' do
|
|
53
|
+
entered_activate = Queue.new
|
|
54
|
+
release_activate = Queue.new
|
|
55
|
+
call_count = 0
|
|
56
|
+
|
|
57
|
+
allow(Standby::ConnectionHolder).to receive(:activate).and_wrap_original do |original, target|
|
|
58
|
+
call_count += 1
|
|
59
|
+
if call_count == 1
|
|
60
|
+
entered_activate << true
|
|
61
|
+
release_activate.pop
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
original.call(target)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
t1 = Thread.new { Standby.connection_holder(:standby) }
|
|
68
|
+
entered_activate.pop
|
|
69
|
+
|
|
70
|
+
t2 = Thread.new { Standby.connection_holder(:standby) }
|
|
71
|
+
|
|
72
|
+
expect(t2.join(0.1)).to be_nil
|
|
73
|
+
expect(call_count).to eq(1)
|
|
74
|
+
|
|
75
|
+
release_activate << true
|
|
76
|
+
|
|
77
|
+
[t1, t2].each(&:join)
|
|
78
|
+
|
|
79
|
+
expect(Standby.connection_holder(:standby).name).to eq('StandbyStandbyConnectionHolder')
|
|
80
|
+
expect(call_count).to eq(1)
|
|
81
|
+
end
|
|
48
82
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -52,7 +52,11 @@ class Seeder
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def connect(env)
|
|
55
|
+
ActiveRecord::Base.connection_pool.disconnect! if ActiveRecord::Base.connected?
|
|
55
56
|
ActiveRecord::Base.establish_connection(env)
|
|
57
|
+
return unless ActiveRecord::Base.connection.adapter_name == 'SQLite'
|
|
58
|
+
|
|
59
|
+
ActiveRecord::Base.connection.execute('PRAGMA journal_mode=DELETE')
|
|
56
60
|
end
|
|
57
61
|
end
|
|
58
62
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: standby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kenn Ejima
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -89,6 +88,7 @@ files:
|
|
|
89
88
|
- bin/console
|
|
90
89
|
- gemfiles/rails4.2.gemfile
|
|
91
90
|
- gemfiles/rails5.2.gemfile
|
|
91
|
+
- gemfiles/rails6.1.gemfile
|
|
92
92
|
- gemfiles/rails7.0.gemfile
|
|
93
93
|
- lib/standby.rb
|
|
94
94
|
- lib/standby/active_record/base.rb
|
|
@@ -108,7 +108,6 @@ files:
|
|
|
108
108
|
homepage: https://github.com/kenn/standby
|
|
109
109
|
licenses: []
|
|
110
110
|
metadata: {}
|
|
111
|
-
post_install_message:
|
|
112
111
|
rdoc_options: []
|
|
113
112
|
require_paths:
|
|
114
113
|
- lib
|
|
@@ -123,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
123
122
|
- !ruby/object:Gem::Version
|
|
124
123
|
version: '0'
|
|
125
124
|
requirements: []
|
|
126
|
-
rubygems_version: 3.
|
|
127
|
-
signing_key:
|
|
125
|
+
rubygems_version: 3.6.9
|
|
128
126
|
specification_version: 4
|
|
129
127
|
summary: Read from stand-by databases for ActiveRecord
|
|
130
128
|
test_files:
|