rails_failover 0.6.4 → 0.8.0

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
  SHA256:
3
- metadata.gz: 651969085a16547763a2df77d40285f300c602fea51089989ec4b6fe62832c3d
4
- data.tar.gz: aed0094cc23da42f1870ace6b94badc64493f2bf85053ab387bd22919c5e939a
3
+ metadata.gz: 146164de9729fe33317969e8d3ca2c5c79980e947f93dfd32b6673a1a95061a6
4
+ data.tar.gz: d3e6eb2cee6bcf663115e72c9e62d62e3f869753549fdcff55381ca4405842c1
5
5
  SHA512:
6
- metadata.gz: b9310d55228dee7660d2e616349b014652c5eb5559b5db0f85a915500dfdde693843d6f9c1abb3195749bb7d7b4cfe1ca3341deedb1e8b68b86c7d14c567485f
7
- data.tar.gz: 81bb776dac713ab01d1833346658be050488b3c24687bd4c603b3e47b3c444e83bb709074576e4a796da637a449914e6916420b505176a022fd51b92b6a42115
6
+ metadata.gz: 1554851137a5251f524574f7d0120924910ad3dc755ad336e9c29c7404cf515d79dad9cb538f06b4084363d919f37586f412f5702fb92a2c85678bd161349fd3
7
+ data.tar.gz: 0f2a72692577a2be3d961da51be3ba150b7e7311fbe2932b062443d2a10dba6014e04268be105a815ab08169b542aa0d3a26dbe36611f036eecdc7a17bb527ac
@@ -5,8 +5,7 @@ on:
5
5
  push:
6
6
  branches:
7
7
  - master
8
- tags:
9
- - v*
8
+ - main
10
9
 
11
10
  jobs:
12
11
  build:
@@ -18,22 +17,19 @@ jobs:
18
17
  strategy:
19
18
  fail-fast: false
20
19
  matrix:
21
- ruby:
22
- - 2.6
23
- - 2.7
24
- build_types: ["LINT", "REDIS", "ACTIVERECORD"]
25
- exclude:
26
- - ruby: 2.6
20
+ ruby: ["2.6", "2.7", "3.0", "3.1"]
21
+ build_types: ["REDIS", "ACTIVERECORD"]
22
+ include:
23
+ - ruby: "3.1"
27
24
  build_types: "LINT"
28
25
 
29
26
  steps:
30
- - uses: actions/checkout@v1
27
+ - uses: actions/checkout@v2
31
28
 
32
29
  - name: Setup ruby
33
- uses: actions/setup-ruby@v1
30
+ uses: ruby/setup-ruby@v1
34
31
  with:
35
32
  ruby-version: ${{ matrix.ruby }}
36
- architecture: 'x64'
37
33
 
38
34
  - name: Setup bundler
39
35
  run: gem install bundler
@@ -68,7 +64,7 @@ jobs:
68
64
  if: env.BUILD_TYPE == 'ACTIVERECORD'
69
65
 
70
66
  publish:
71
- if: contains(github.ref, 'refs/tags/v')
67
+ if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
72
68
  needs: build
73
69
  runs-on: ubuntu-latest
74
70
 
@@ -76,6 +72,8 @@ jobs:
76
72
  - uses: actions/checkout@v2
77
73
 
78
74
  - name: Release Gem
79
- uses: CvX/publish-rubygems-action@master
75
+ uses: discourse/publish-rubygems-action@v2
80
76
  env:
81
- RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
77
+ RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
78
+ GIT_EMAIL: team@discourse.org
79
+ GIT_NAME: discoursebot
data/.gitignore CHANGED
@@ -16,3 +16,4 @@
16
16
  *.rdb
17
17
 
18
18
  *.gem
19
+ Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -6,6 +6,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.8.0] - 2022-01-17
10
+
11
+ - FEATURE: Compatibility with Rails 7.0+
12
+
13
+ ## [0.7.3] - 2021-04-15
14
+
15
+ - FEATURE: Compatibility with Rails 6.1
16
+
17
+ ## [0.7.2] - 2021-04-14
18
+
19
+ No changes.
20
+
21
+ ## [0.7.1] - 2021-04-14
22
+
23
+ - FIX: Backward compatability with Rails 6.0
24
+
25
+ ## [0.7.0] - 2021-04-14
26
+
27
+ - FEATURE: Partial compatibility with Rails 6.1
28
+
29
+ ## [0.6.5] - 2020-12-16
30
+
31
+ - FIX: Catch exceptions that are not intercepted by `ActionDispatch::DebugExceptions`.
32
+
9
33
  ## [0.6.4] - 2020-12-09
10
34
 
11
35
  - FIX: Handle the case when the replica is set equal to the primary
@@ -31,7 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
55
 
32
56
  - FEATURE: Add primaries_down_count function to failover handlers
33
57
 
34
- This is intended for consumption by monitoring systems (e.g. the Discourse prometheus exporter)
58
+ This is intended for consumption by monitoring systems (e.g. the Discourse prometheus exporter)
35
59
 
36
60
  ## [0.5.9] - 2020-11-06
37
61
  - FIX: Ignore errors from the redis socket shutdown call
@@ -56,13 +56,20 @@ module RailsFailover
56
56
 
57
57
  primaries_down.keys.each do |handler_key|
58
58
  connection_handler = ::ActiveRecord::Base.connection_handlers[handler_key]
59
- spec = connection_handler.retrieve_connection_pool(spec_name).spec
60
- config = spec.config
59
+
60
+ connection_pool = connection_handler.retrieve_connection_pool(spec_name)
61
+ if connection_pool.respond_to?(:db_config)
62
+ config = connection_pool.db_config.configuration_hash
63
+ adapter_method = connection_pool.db_config.adapter_method
64
+ else
65
+ config = connection_pool.spec.config
66
+ adapter_method = connection_pool.spec.adapter_method
67
+ end
61
68
  logger.debug "#{Process.pid} Checking server for '#{handler_key} #{spec_name}'..."
62
69
  connection_active = false
63
70
 
64
71
  begin
65
- connection = ::ActiveRecord::Base.public_send(spec.adapter_method, config)
72
+ connection = ::ActiveRecord::Base.public_send(adapter_method, config)
66
73
  connection_active = connection.active?
67
74
  rescue => e
68
75
  logger.debug "#{Process.pid} Connection to server for '#{handler_key} #{spec_name}' failed with '#{e.message}'"
@@ -14,10 +14,17 @@ module RailsFailover
14
14
  end
15
15
 
16
16
  def self.handle(request, exception)
17
+ verify_primary(
18
+ exception,
19
+ request.env[Middleware::WRITING_ROLE_HEADER]
20
+ )
21
+ end
22
+
23
+ def self.verify_primary(exception, writing_role)
17
24
  exception = resolve_cause(exception)
18
25
 
19
26
  if adapter_errors.any? { |error| exception.is_a?(error) }
20
- Handler.instance.verify_primary(request.env[Middleware::WRITING_ROLE_HEADER])
27
+ Handler.instance.verify_primary(writing_role)
21
28
  end
22
29
  end
23
30
 
@@ -61,6 +68,9 @@ module RailsFailover
61
68
  env[WRITING_ROLE_HEADER] = writing_role
62
69
  @app.call(env)
63
70
  end
71
+ rescue => e
72
+ Interceptor.verify_primary(e, writing_role) if writing_role
73
+ raise e
64
74
  end
65
75
 
66
76
  private
@@ -70,7 +80,12 @@ module RailsFailover
70
80
  handler = ::ActiveRecord::ConnectionAdapters::ConnectionHandler.new
71
81
 
72
82
  ::ActiveRecord::Base.connection_handlers[writing_role].connection_pools.each do |pool|
73
- ::RailsFailover::ActiveRecord.establish_reading_connection(handler, pool.spec)
83
+ if pool.respond_to?(:db_config)
84
+ config = pool.db_config.configuration_hash
85
+ else
86
+ config = pool.spec.config
87
+ end
88
+ ::RailsFailover::ActiveRecord.establish_reading_connection(handler, config)
74
89
  end
75
90
 
76
91
  handler
@@ -4,7 +4,15 @@ module RailsFailover
4
4
  module ActiveRecord
5
5
  class Railtie < ::Rails::Railtie
6
6
  initializer "rails_failover.init", after: "active_record.initialize_database" do |app|
7
- config = ::ActiveRecord::Base.connection_config
7
+
8
+ # AR 6.0 / 6.1 compat
9
+ config =
10
+ if ::ActiveRecord::Base.respond_to? :connection_db_config
11
+ ::ActiveRecord::Base.connection_db_config.configuration_hash
12
+ else
13
+ ::ActiveRecord::Base.connection_config
14
+ end
15
+
8
16
  app.config.active_record_rails_failover = false
9
17
 
10
18
  if !!(config[:replica_host] && config[:replica_port])
@@ -19,9 +27,14 @@ module RailsFailover
19
27
  ::ActiveRecord::ConnectionAdapters::ConnectionHandler.new
20
28
 
21
29
  ::ActiveRecord::Base.connection_handlers[::ActiveRecord::Base.writing_role].connection_pools.each do |connection_pool|
30
+ if connection_pool.respond_to?(:db_config)
31
+ config = connection_pool.db_config.configuration_hash
32
+ else
33
+ config = connection_pool.spec.config
34
+ end
22
35
  RailsFailover::ActiveRecord.establish_reading_connection(
23
36
  ::ActiveRecord::Base.connection_handlers[::ActiveRecord::Base.reading_role],
24
- connection_pool.spec
37
+ config
25
38
  )
26
39
  end
27
40
 
@@ -29,7 +42,7 @@ module RailsFailover
29
42
  ::ActiveRecord::Base.connection
30
43
  rescue ::ActiveRecord::NoDatabaseError
31
44
  # Do nothing since database hasn't been created
32
- rescue ::PG::Error => e
45
+ rescue ::PG::Error, ::ActiveRecord::ConnectionNotEstablished
33
46
  Handler.instance.verify_primary(::ActiveRecord::Base.writing_role)
34
47
  ::ActiveRecord::Base.connection_handler = ::ActiveRecord::Base.lookup_connection_handler(:reading)
35
48
  end
@@ -27,8 +27,7 @@ module RailsFailover
27
27
  @verify_primary_frequency_seconds || 5
28
28
  end
29
29
 
30
- def self.establish_reading_connection(handler, connection_spec)
31
- config = connection_spec.config
30
+ def self.establish_reading_connection(handler, config)
32
31
 
33
32
  if config[:replica_host] && config[:replica_port]
34
33
  replica_config = config.dup
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsFailover
4
- VERSION = "0.6.4"
4
+ VERSION = "0.8.0"
5
5
  end
data/makefile CHANGED
@@ -9,7 +9,7 @@ test_active_record:
9
9
  @ACTIVE_RECORD=1 bundle exec rspec --tag type:active_record ${RSPEC_PATH}
10
10
 
11
11
  setup_dummy_rails_server:
12
- @cd spec/support/dummy_app && bundle install --quiet --without test --without development && yarn install && RAILS_ENV=production $(BUNDLER_BIN) exec rails db:create db:migrate db:seed
12
+ @cd spec/support/dummy_app && bundle install --quiet && yarn install && RAILS_ENV=production $(BUNDLER_BIN) exec rails db:create db:migrate db:seed
13
13
 
14
14
  start_dummy_rails_server:
15
15
  @cd spec/support/dummy_app && BUNDLE_GEMFILE=Gemfile UNICORN_WORKERS=5 SECRET_KEY_BASE=somekey bundle exec unicorn -c config/unicorn.conf.rb -D -E production
@@ -9,8 +9,9 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["tgx@discourse.org"]
10
10
 
11
11
  spec.summary = %q{Failover for ActiveRecord and Redis}
12
+ spec.homepage = "https://github.com/discourse/rails_failover"
12
13
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
14
15
 
15
16
  # Specify which files should be added to the gem when it is released.
16
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -21,8 +22,8 @@ Gem::Specification.new do |spec|
21
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
23
  spec.require_paths = ["lib"]
23
24
 
24
- ["activerecord", "railties"].each do |gem_name|
25
- spec.add_dependency gem_name, "~> 6.0"
26
- end
25
+ spec.add_dependency "activerecord", "> 6.0", "< 7.1"
26
+ spec.add_dependency "railties", "> 6.0", "< 7.1"
27
+
27
28
  spec.add_dependency "concurrent-ruby"
28
29
  end
metadata CHANGED
@@ -1,43 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_failover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Tan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-09 00:00:00.000000000 Z
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '6.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7.1'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">"
25
28
  - !ruby/object:Gem::Version
26
29
  version: '6.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7.1'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: railties
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">"
32
38
  - !ruby/object:Gem::Version
33
39
  version: '6.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '7.1'
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - "~>"
47
+ - - ">"
39
48
  - !ruby/object:Gem::Version
40
49
  version: '6.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '7.1'
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: concurrent-ruby
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +78,6 @@ files:
66
78
  - CHANGELOG.md
67
79
  - CODE_OF_CONDUCT.md
68
80
  - Gemfile
69
- - Gemfile.lock
70
81
  - LICENSE.txt
71
82
  - README.md
72
83
  - Rakefile
@@ -87,7 +98,7 @@ files:
87
98
  - postgresql.mk
88
99
  - rails_failover.gemspec
89
100
  - redis.mk
90
- homepage:
101
+ homepage: https://github.com/discourse/rails_failover
91
102
  licenses:
92
103
  - MIT
93
104
  metadata: {}
@@ -99,14 +110,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
110
  requirements:
100
111
  - - ">="
101
112
  - !ruby/object:Gem::Version
102
- version: 2.3.0
113
+ version: 2.5.0
103
114
  required_rubygems_version: !ruby/object:Gem::Requirement
104
115
  requirements:
105
116
  - - ">="
106
117
  - !ruby/object:Gem::Version
107
118
  version: '0'
108
119
  requirements: []
109
- rubygems_version: 3.0.3
120
+ rubygems_version: 3.1.6
110
121
  signing_key:
111
122
  specification_version: 4
112
123
  summary: Failover for ActiveRecord and Redis
data/Gemfile.lock DELETED
@@ -1,123 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- rails_failover (0.6.4)
5
- activerecord (~> 6.0)
6
- concurrent-ruby
7
- railties (~> 6.0)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actionpack (6.0.3.1)
13
- actionview (= 6.0.3.1)
14
- activesupport (= 6.0.3.1)
15
- rack (~> 2.0, >= 2.0.8)
16
- rack-test (>= 0.6.3)
17
- rails-dom-testing (~> 2.0)
18
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
19
- actionview (6.0.3.1)
20
- activesupport (= 6.0.3.1)
21
- builder (~> 3.1)
22
- erubi (~> 1.4)
23
- rails-dom-testing (~> 2.0)
24
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
25
- activemodel (6.0.3.1)
26
- activesupport (= 6.0.3.1)
27
- activerecord (6.0.3.1)
28
- activemodel (= 6.0.3.1)
29
- activesupport (= 6.0.3.1)
30
- activesupport (6.0.3.1)
31
- concurrent-ruby (~> 1.0, >= 1.0.2)
32
- i18n (>= 0.7, < 2)
33
- minitest (~> 5.1)
34
- tzinfo (~> 1.1)
35
- zeitwerk (~> 2.2, >= 2.2.2)
36
- ast (2.4.0)
37
- builder (3.2.4)
38
- byebug (11.1.3)
39
- concurrent-ruby (1.1.6)
40
- crass (1.0.6)
41
- diff-lcs (1.3)
42
- erubi (1.10.0)
43
- i18n (1.8.2)
44
- concurrent-ruby (~> 1.0)
45
- loofah (2.7.0)
46
- crass (~> 1.0.2)
47
- nokogiri (>= 1.5.9)
48
- method_source (1.0.0)
49
- mini_portile2 (2.4.0)
50
- minitest (5.14.1)
51
- nokogiri (1.10.10)
52
- mini_portile2 (~> 2.4.0)
53
- parallel (1.19.1)
54
- parser (2.7.1.2)
55
- ast (~> 2.4.0)
56
- pg (1.2.3)
57
- rack (2.2.3)
58
- rack-test (1.1.0)
59
- rack (>= 1.0, < 3)
60
- rails-dom-testing (2.0.3)
61
- activesupport (>= 4.2.0)
62
- nokogiri (>= 1.6)
63
- rails-html-sanitizer (1.3.0)
64
- loofah (~> 2.3)
65
- railties (6.0.3.1)
66
- actionpack (= 6.0.3.1)
67
- activesupport (= 6.0.3.1)
68
- method_source
69
- rake (>= 0.8.7)
70
- thor (>= 0.20.3, < 2.0)
71
- rainbow (3.0.0)
72
- rake (12.3.3)
73
- redis (4.1.4)
74
- rexml (3.2.4)
75
- rspec (3.9.0)
76
- rspec-core (~> 3.9.0)
77
- rspec-expectations (~> 3.9.0)
78
- rspec-mocks (~> 3.9.0)
79
- rspec-core (3.9.2)
80
- rspec-support (~> 3.9.3)
81
- rspec-expectations (3.9.2)
82
- diff-lcs (>= 1.2.0, < 2.0)
83
- rspec-support (~> 3.9.0)
84
- rspec-mocks (3.9.1)
85
- diff-lcs (>= 1.2.0, < 2.0)
86
- rspec-support (~> 3.9.0)
87
- rspec-support (3.9.3)
88
- rubocop (0.83.0)
89
- parallel (~> 1.10)
90
- parser (>= 2.7.0.1)
91
- rainbow (>= 2.2.2, < 4.0)
92
- rexml
93
- ruby-progressbar (~> 1.7)
94
- unicode-display_width (>= 1.4.0, < 2.0)
95
- rubocop-discourse (2.1.2)
96
- rubocop (>= 0.69.0)
97
- rubocop-rspec (>= 1.39.0)
98
- rubocop-rspec (1.39.0)
99
- rubocop (>= 0.68.1)
100
- ruby-progressbar (1.10.1)
101
- thor (1.0.1)
102
- thread_safe (0.3.6)
103
- tzinfo (1.2.7)
104
- thread_safe (~> 0.1)
105
- unicode-display_width (1.7.0)
106
- zeitwerk (2.3.0)
107
-
108
- PLATFORMS
109
- ruby
110
-
111
- DEPENDENCIES
112
- activerecord (~> 6.0)
113
- byebug
114
- pg (~> 1.2)
115
- rack
116
- rails_failover!
117
- rake (~> 12.0)
118
- redis (~> 4.1)
119
- rspec (~> 3.0)
120
- rubocop-discourse
121
-
122
- BUNDLED WITH
123
- 2.1.4