rails_failover 0.6.4 → 0.8.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 +12 -14
- data/.gitignore +1 -0
- data/CHANGELOG.md +25 -1
- data/lib/rails_failover/active_record/handler.rb +10 -3
- data/lib/rails_failover/active_record/middleware.rb +17 -2
- data/lib/rails_failover/active_record/railtie.rb +16 -3
- data/lib/rails_failover/active_record.rb +1 -2
- data/lib/rails_failover/version.rb +1 -1
- data/makefile +1 -1
- data/rails_failover.gemspec +5 -4
- metadata +21 -10
- data/Gemfile.lock +0 -123
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 146164de9729fe33317969e8d3ca2c5c79980e947f93dfd32b6673a1a95061a6
|
4
|
+
data.tar.gz: d3e6eb2cee6bcf663115e72c9e62d62e3f869753549fdcff55381ca4405842c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1554851137a5251f524574f7d0120924910ad3dc755ad336e9c29c7404cf515d79dad9cb538f06b4084363d919f37586f412f5702fb92a2c85678bd161349fd3
|
7
|
+
data.tar.gz: 0f2a72692577a2be3d961da51be3ba150b7e7311fbe2932b062443d2a10dba6014e04268be105a815ab08169b542aa0d3a26dbe36611f036eecdc7a17bb527ac
|
data/.github/workflows/ci.yml
CHANGED
@@ -5,8 +5,7 @@ on:
|
|
5
5
|
push:
|
6
6
|
branches:
|
7
7
|
- master
|
8
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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@
|
27
|
+
- uses: actions/checkout@v2
|
31
28
|
|
32
29
|
- name: Setup ruby
|
33
|
-
uses:
|
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:
|
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:
|
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
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
|
-
|
60
|
-
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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,
|
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
|
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
|
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
|
data/rails_failover.gemspec
CHANGED
@@ -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.
|
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
|
-
|
25
|
-
|
26
|
-
|
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.
|
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:
|
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.
|
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.
|
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
|