janus-ar 8.0.1 → 8.1.1
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/Gemfile +1 -3
- data/Gemfile.lock +27 -24
- data/README.md +69 -3
- data/Rakefile +0 -2
- data/janus-ar.gemspec +7 -6
- data/lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter.rb +0 -2
- data/lib/janus-ar/active_record/connection_adapters/janus_postgresql_adapter.rb +42 -0
- data/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter.rb +0 -2
- data/lib/janus-ar/adapter_extensions.rb +21 -6
- data/lib/janus-ar/client.rb +5 -6
- data/lib/janus-ar/context.rb +0 -2
- data/lib/janus-ar/db_console_config.rb +15 -17
- data/lib/janus-ar/logging/logger.rb +13 -15
- data/lib/janus-ar/logging/subscriber.rb +25 -27
- data/lib/janus-ar/query_director.rb +15 -4
- data/lib/janus-ar/railtie.rb +0 -2
- data/lib/janus-ar/version.rb +1 -3
- data/lib/janus-ar.rb +0 -2
- metadata +23 -31
- data/.bundle/config +0 -5
- data/.github/dependabot.yml +0 -7
- data/.github/workflows/ci.yml +0 -68
- data/.github/workflows/publish.yml +0 -25
- data/.gitignore +0 -3
- data/.rspec +0 -3
- data/.rubocop.yml +0 -29
- data/assets/.gitkeep +0 -1
- data/assets/janus-logo.png +0 -0
- data/bin/release.sh +0 -4
- data/gemfiles/activerecord_8_0.gemfile +0 -7
- data/gemfiles/activerecord_8_1.gemfile +0 -7
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb +0 -78
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb +0 -77
- data/spec/lib/janus-ar/client_spec.rb +0 -7
- data/spec/lib/janus-ar/context_spec.rb +0 -118
- data/spec/lib/janus-ar/db_console_config_spec.rb +0 -28
- data/spec/lib/janus-ar/logging/logger_spec.rb +0 -31
- data/spec/lib/janus-ar/logging/subscriber_spec.rb +0 -58
- data/spec/lib/janus-ar/query_director_spec.rb +0 -141
- data/spec/shared_examples/a_mysql_like_server.rb +0 -155
- data/spec/spec_helper.rb +0 -46
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: janus-ar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lloyd Watkin
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activerecord
|
|
@@ -57,6 +57,20 @@ dependencies:
|
|
|
57
57
|
- - ">="
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
59
|
version: '0'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: pg
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '0'
|
|
67
|
+
type: :development
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
60
74
|
- !ruby/object:Gem::Dependency
|
|
61
75
|
name: trilogy
|
|
62
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -119,28 +133,28 @@ dependencies:
|
|
|
119
133
|
requirements:
|
|
120
134
|
- - "~>"
|
|
121
135
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: 1.
|
|
136
|
+
version: 1.90.0
|
|
123
137
|
type: :development
|
|
124
138
|
prerelease: false
|
|
125
139
|
version_requirements: !ruby/object:Gem::Requirement
|
|
126
140
|
requirements:
|
|
127
141
|
- - "~>"
|
|
128
142
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: 1.
|
|
143
|
+
version: 1.90.0
|
|
130
144
|
- !ruby/object:Gem::Dependency
|
|
131
145
|
name: rubocop-rails
|
|
132
146
|
requirement: !ruby/object:Gem::Requirement
|
|
133
147
|
requirements:
|
|
134
148
|
- - "~>"
|
|
135
149
|
- !ruby/object:Gem::Version
|
|
136
|
-
version: 2.
|
|
150
|
+
version: 2.37.0
|
|
137
151
|
type: :development
|
|
138
152
|
prerelease: false
|
|
139
153
|
version_requirements: !ruby/object:Gem::Requirement
|
|
140
154
|
requirements:
|
|
141
155
|
- - "~>"
|
|
142
156
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: 2.
|
|
157
|
+
version: 2.37.0
|
|
144
158
|
- !ruby/object:Gem::Dependency
|
|
145
159
|
name: rubocop-rspec
|
|
146
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -186,32 +200,20 @@ dependencies:
|
|
|
186
200
|
description: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
187
201
|
email:
|
|
188
202
|
- lloyd@olioex.com
|
|
189
|
-
executables:
|
|
190
|
-
- release.sh
|
|
203
|
+
executables: []
|
|
191
204
|
extensions: []
|
|
192
205
|
extra_rdoc_files: []
|
|
193
206
|
files:
|
|
194
|
-
- ".bundle/config"
|
|
195
|
-
- ".github/dependabot.yml"
|
|
196
|
-
- ".github/workflows/ci.yml"
|
|
197
|
-
- ".github/workflows/publish.yml"
|
|
198
|
-
- ".gitignore"
|
|
199
|
-
- ".rspec"
|
|
200
|
-
- ".rubocop.yml"
|
|
201
207
|
- CODE_OF_CONDUCT.md
|
|
202
208
|
- Gemfile
|
|
203
209
|
- Gemfile.lock
|
|
204
210
|
- LICENSE
|
|
205
211
|
- README.md
|
|
206
212
|
- Rakefile
|
|
207
|
-
- assets/.gitkeep
|
|
208
|
-
- assets/janus-logo.png
|
|
209
|
-
- bin/release.sh
|
|
210
|
-
- gemfiles/activerecord_8_0.gemfile
|
|
211
|
-
- gemfiles/activerecord_8_1.gemfile
|
|
212
213
|
- janus-ar.gemspec
|
|
213
214
|
- lib/janus-ar.rb
|
|
214
215
|
- lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter.rb
|
|
216
|
+
- lib/janus-ar/active_record/connection_adapters/janus_postgresql_adapter.rb
|
|
215
217
|
- lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter.rb
|
|
216
218
|
- lib/janus-ar/adapter_extensions.rb
|
|
217
219
|
- lib/janus-ar/client.rb
|
|
@@ -222,16 +224,6 @@ files:
|
|
|
222
224
|
- lib/janus-ar/query_director.rb
|
|
223
225
|
- lib/janus-ar/railtie.rb
|
|
224
226
|
- lib/janus-ar/version.rb
|
|
225
|
-
- spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb
|
|
226
|
-
- spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb
|
|
227
|
-
- spec/lib/janus-ar/client_spec.rb
|
|
228
|
-
- spec/lib/janus-ar/context_spec.rb
|
|
229
|
-
- spec/lib/janus-ar/db_console_config_spec.rb
|
|
230
|
-
- spec/lib/janus-ar/logging/logger_spec.rb
|
|
231
|
-
- spec/lib/janus-ar/logging/subscriber_spec.rb
|
|
232
|
-
- spec/lib/janus-ar/query_director_spec.rb
|
|
233
|
-
- spec/shared_examples/a_mysql_like_server.rb
|
|
234
|
-
- spec/spec_helper.rb
|
|
235
227
|
homepage: https://github.com/olioex/janus-ar
|
|
236
228
|
licenses:
|
|
237
229
|
- MIT
|
|
@@ -251,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
251
243
|
- !ruby/object:Gem::Version
|
|
252
244
|
version: '0'
|
|
253
245
|
requirements: []
|
|
254
|
-
rubygems_version: 3.6.
|
|
246
|
+
rubygems_version: 3.6.9
|
|
255
247
|
specification_version: 4
|
|
256
248
|
summary: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
257
249
|
test_files: []
|
data/.bundle/config
DELETED
data/.github/dependabot.yml
DELETED
data/.github/workflows/ci.yml
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
pull_request:
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
strategy:
|
|
13
|
-
fail-fast: false
|
|
14
|
-
matrix:
|
|
15
|
-
ruby:
|
|
16
|
-
- '3.2'
|
|
17
|
-
- '3.3'
|
|
18
|
-
- '3.4'
|
|
19
|
-
- '4.0'
|
|
20
|
-
gemfile:
|
|
21
|
-
- gemfiles/activerecord_8_0.gemfile
|
|
22
|
-
- gemfiles/activerecord_8_1.gemfile
|
|
23
|
-
name: Ruby ${{ matrix.ruby }} / ${{ matrix.gemfile }}
|
|
24
|
-
env:
|
|
25
|
-
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
26
|
-
services:
|
|
27
|
-
mysql:
|
|
28
|
-
image: mysql:8.0
|
|
29
|
-
env:
|
|
30
|
-
MYSQL_DATABASE: test
|
|
31
|
-
MYSQL_ROOT_PASSWORD: password
|
|
32
|
-
MYSQL_USER: test
|
|
33
|
-
MYSQL_PASSWORD: test_password
|
|
34
|
-
ports:
|
|
35
|
-
- 3306:3306
|
|
36
|
-
options: >-
|
|
37
|
-
--health-cmd "mysqladmin ping"
|
|
38
|
-
--health-interval 10s
|
|
39
|
-
--health-timeout 5s
|
|
40
|
-
--health-retries 5
|
|
41
|
-
steps:
|
|
42
|
-
- uses: actions/checkout@v4
|
|
43
|
-
- uses: ruby/setup-ruby@v1
|
|
44
|
-
with:
|
|
45
|
-
ruby-version: ${{ matrix.ruby }}
|
|
46
|
-
bundler-cache: true
|
|
47
|
-
- run: |
|
|
48
|
-
mysql -e "CREATE USER 'replica'@'%' IDENTIFIED BY 'replica_password';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
49
|
-
mysql -e "GRANT SELECT ON test.* TO 'replica'@'%'" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
50
|
-
|
|
51
|
-
mysql -e "CREATE USER 'primary'@'%' IDENTIFIED BY 'primary_password';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
52
|
-
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'primary'@'%';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
53
|
-
mysql -e "FLUSH PRIVILEGES;" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
54
|
-
- run: |
|
|
55
|
-
bundle exec rspec
|
|
56
|
-
env:
|
|
57
|
-
MYSQL_HOST: 127.0.0.1
|
|
58
|
-
RAILS_ENV: test
|
|
59
|
-
RuboCop:
|
|
60
|
-
runs-on: ubuntu-latest
|
|
61
|
-
steps:
|
|
62
|
-
- uses: actions/checkout@v4
|
|
63
|
-
- uses: ruby/setup-ruby@v1
|
|
64
|
-
with:
|
|
65
|
-
ruby-version: '3.2'
|
|
66
|
-
bundler-cache: true
|
|
67
|
-
- run: |
|
|
68
|
-
bundle exec rubocop --parallel --color
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: Publish GEM
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- v*
|
|
7
|
-
jobs:
|
|
8
|
-
push:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write
|
|
13
|
-
id-token: write
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
# Set up
|
|
17
|
-
- uses: actions/checkout@v4
|
|
18
|
-
- name: Set up Ruby
|
|
19
|
-
uses: ruby/setup-ruby@v1
|
|
20
|
-
with:
|
|
21
|
-
bundler-cache: true
|
|
22
|
-
ruby-version: ruby
|
|
23
|
-
|
|
24
|
-
# Release
|
|
25
|
-
- uses: rubygems/release-gem@v1
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
inherit_from:
|
|
2
|
-
- https://tech.olioex.com/.support/rubocop-styling-v1.0
|
|
3
|
-
|
|
4
|
-
require:
|
|
5
|
-
- rubocop-rails
|
|
6
|
-
|
|
7
|
-
AllCops:
|
|
8
|
-
SuggestExtensions: false
|
|
9
|
-
|
|
10
|
-
Style/Documentation:
|
|
11
|
-
Enabled: false
|
|
12
|
-
|
|
13
|
-
Rails/Delegate:
|
|
14
|
-
Enabled: false
|
|
15
|
-
|
|
16
|
-
Metrics/BlockLength:
|
|
17
|
-
Exclude:
|
|
18
|
-
- spec/**/*
|
|
19
|
-
|
|
20
|
-
Style/GlobalVars:
|
|
21
|
-
Exclude:
|
|
22
|
-
- 'spec/**/*'
|
|
23
|
-
|
|
24
|
-
Naming/FileName:
|
|
25
|
-
Exclude:
|
|
26
|
-
- lib/janus-ar.rb
|
|
27
|
-
|
|
28
|
-
Metrics/AbcSize:
|
|
29
|
-
Max: 25
|
data/assets/.gitkeep
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
data/assets/janus-logo.png
DELETED
|
Binary file
|
data/bin/release.sh
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe ActiveRecord::ConnectionAdapters::JanusMysql2Adapter do
|
|
4
|
-
subject { described_class.new(config) }
|
|
5
|
-
|
|
6
|
-
let(:database) { 'test' }
|
|
7
|
-
let(:primary_config) do
|
|
8
|
-
{
|
|
9
|
-
'username' => 'primary',
|
|
10
|
-
'password' => 'primary_password',
|
|
11
|
-
'host' => '127.0.0.1',
|
|
12
|
-
'ssl' => true,
|
|
13
|
-
'ssl_mode' => 'REQUIRED',
|
|
14
|
-
'tls_min_version' => 3,
|
|
15
|
-
}
|
|
16
|
-
end
|
|
17
|
-
let(:replica_config) do
|
|
18
|
-
{
|
|
19
|
-
'username' => 'replica',
|
|
20
|
-
'password' => 'replica_password',
|
|
21
|
-
'host' => '127.0.0.1',
|
|
22
|
-
'pool' => 500,
|
|
23
|
-
'ssl' => true,
|
|
24
|
-
'ssl_mode' => 'REQUIRED',
|
|
25
|
-
'tls_min_version' => 3,
|
|
26
|
-
}
|
|
27
|
-
end
|
|
28
|
-
let(:config) do
|
|
29
|
-
{
|
|
30
|
-
database:,
|
|
31
|
-
adapter: 'janus_mysql2',
|
|
32
|
-
janus: {
|
|
33
|
-
'primary' => primary_config,
|
|
34
|
-
'replica' => replica_config,
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe 'Configuration' do
|
|
40
|
-
it 'creates primary connection as expected' do
|
|
41
|
-
config = primary_config.dup.freeze
|
|
42
|
-
expect(subject.config).to eq config.merge('database' => database,
|
|
43
|
-
'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it 'creates replica connection as expected' do
|
|
47
|
-
config = replica_config.dup.freeze
|
|
48
|
-
expect(
|
|
49
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
50
|
-
).to eq config.merge('database' => database, 'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context 'Rails sets empty database for server connection' do
|
|
54
|
-
let(:database) { nil }
|
|
55
|
-
|
|
56
|
-
it 'creates primary connection as expected' do
|
|
57
|
-
config = primary_config.dup.freeze
|
|
58
|
-
expect(subject.config).to eq config.merge(
|
|
59
|
-
'database' => nil,
|
|
60
|
-
'flags' => ::Janus::Client::FOUND_ROWS
|
|
61
|
-
).symbolize_keys
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
it 'creates replica connection as expected' do
|
|
65
|
-
config = replica_config.dup.freeze
|
|
66
|
-
expect(
|
|
67
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
68
|
-
).to eq config.merge('database' => nil, 'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
describe 'Integration tests' do
|
|
74
|
-
let(:table_name) { 'table_name_mysql2' }
|
|
75
|
-
|
|
76
|
-
it_behaves_like 'a mysql like server'
|
|
77
|
-
end
|
|
78
|
-
end
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe ActiveRecord::ConnectionAdapters::JanusTrilogyAdapter do
|
|
4
|
-
subject { described_class.new(config) }
|
|
5
|
-
|
|
6
|
-
let(:database) { 'test' }
|
|
7
|
-
let(:primary_config) do
|
|
8
|
-
{
|
|
9
|
-
'username' => 'primary',
|
|
10
|
-
'password' => 'primary_password',
|
|
11
|
-
'host' => '127.0.0.1',
|
|
12
|
-
'ssl' => true,
|
|
13
|
-
'ssl_mode' => 'REQUIRED',
|
|
14
|
-
'tls_min_version' => Trilogy::TLS_VERSION_12,
|
|
15
|
-
}
|
|
16
|
-
end
|
|
17
|
-
let(:replica_config) do
|
|
18
|
-
{
|
|
19
|
-
'username' => 'replica',
|
|
20
|
-
'password' => 'replica_password',
|
|
21
|
-
'host' => '127.0.0.1',
|
|
22
|
-
'pool' => 500,
|
|
23
|
-
'ssl' => true,
|
|
24
|
-
'ssl_mode' => 'REQUIRED',
|
|
25
|
-
'tls_min_version' => Trilogy::TLS_VERSION_12,
|
|
26
|
-
}
|
|
27
|
-
end
|
|
28
|
-
let(:config) do
|
|
29
|
-
{
|
|
30
|
-
database:,
|
|
31
|
-
adapter: 'janus_trilogy',
|
|
32
|
-
janus: {
|
|
33
|
-
'primary' => primary_config,
|
|
34
|
-
'replica' => replica_config,
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe 'Configuration' do
|
|
40
|
-
# Trilogy enables FOUND_ROWS via the `found_rows` option (not mysql2-style
|
|
41
|
-
# flags), and ActiveRecord's TrilogyAdapter forces it on. We assert it is
|
|
42
|
-
# present even though the supplied config omits it.
|
|
43
|
-
it 'creates primary connection as expected' do
|
|
44
|
-
config = primary_config.dup.freeze
|
|
45
|
-
expect(subject.config).to eq config.merge('database' => database, 'found_rows' => true).symbolize_keys
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'creates replica connection as expected' do
|
|
49
|
-
config = replica_config.dup.freeze
|
|
50
|
-
expect(
|
|
51
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
52
|
-
).to eq config.merge('database' => database, 'found_rows' => true).symbolize_keys
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context 'Rails sets empty database for server connection' do
|
|
56
|
-
let(:database) { nil }
|
|
57
|
-
|
|
58
|
-
it 'creates primary connection as expected' do
|
|
59
|
-
config = primary_config.dup.freeze
|
|
60
|
-
expect(subject.config).to eq config.merge('database' => nil, 'found_rows' => true).symbolize_keys
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it 'creates replica connection as expected' do
|
|
64
|
-
config = replica_config.dup.freeze
|
|
65
|
-
expect(
|
|
66
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
67
|
-
).to eq config.merge('database' => nil, 'found_rows' => true).symbolize_keys
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
describe 'Integration tests' do
|
|
73
|
-
let(:table_name) { 'table_name_trilogy' }
|
|
74
|
-
|
|
75
|
-
it_behaves_like 'a mysql like server'
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'janus-ar/context'
|
|
4
|
-
require 'active_support/executor'
|
|
5
|
-
|
|
6
|
-
RSpec.describe Janus::Context do
|
|
7
|
-
after(:each) { described_class.release_all }
|
|
8
|
-
|
|
9
|
-
describe '#initialize' do
|
|
10
|
-
it 'defaults to the replica and a primary last-used connection' do
|
|
11
|
-
context = described_class.new
|
|
12
|
-
expect(context.use_primary?).to be false
|
|
13
|
-
expect(context.last_used_connection).to eq(:primary)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'can be created pinned to the primary' do
|
|
17
|
-
expect(described_class.new(primary: true).use_primary?).to be true
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe '#stick_to_primary' do
|
|
22
|
-
it 'sets the primary flag to true' do
|
|
23
|
-
context = described_class.new
|
|
24
|
-
context.stick_to_primary
|
|
25
|
-
expect(context.use_primary?).to be true
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe '#release_all' do
|
|
30
|
-
it 'resets the primary flag and the last used connection' do
|
|
31
|
-
context = described_class.new(primary: true)
|
|
32
|
-
context.used_connection(:primary)
|
|
33
|
-
context.release_all
|
|
34
|
-
expect(context.use_primary?).to be false
|
|
35
|
-
expect(context.last_used_connection).to be_nil
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe '#used_connection' do
|
|
40
|
-
it 'sets the last used connection' do
|
|
41
|
-
context = described_class.new
|
|
42
|
-
context.used_connection(:replica)
|
|
43
|
-
expect(context.last_used_connection).to eq(:replica)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
describe 'class-level access' do
|
|
48
|
-
it 'sticks and releases the current execution state' do
|
|
49
|
-
described_class.stick_to_primary
|
|
50
|
-
expect(described_class.use_primary?).to be true
|
|
51
|
-
described_class.release_all
|
|
52
|
-
expect(described_class.use_primary?).to be false
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it 'isolates state between threads' do
|
|
56
|
-
described_class.stick_to_primary
|
|
57
|
-
other = Thread.new { described_class.use_primary? }.value
|
|
58
|
-
expect(other).to be false
|
|
59
|
-
expect(described_class.use_primary?).to be true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it 'isolates the last used connection between threads' do
|
|
63
|
-
described_class.used_connection(:replica)
|
|
64
|
-
other = Thread.new do
|
|
65
|
-
described_class.used_connection(:primary)
|
|
66
|
-
described_class.last_used_connection
|
|
67
|
-
end.value
|
|
68
|
-
expect(other).to eq(:primary)
|
|
69
|
-
expect(described_class.last_used_connection).to eq(:replica)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it 'is safe to release a context that was never touched' do
|
|
73
|
-
Thread.new do
|
|
74
|
-
expect { described_class.release_all }.not_to raise_error
|
|
75
|
-
expect(described_class.use_primary?).to be false
|
|
76
|
-
end.join
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
describe '.install_reset_hook' do
|
|
81
|
-
let(:executor) { Class.new(ActiveSupport::Executor) }
|
|
82
|
-
|
|
83
|
-
it 'releases the context at the start of every executor run' do
|
|
84
|
-
described_class.install_reset_hook(executor)
|
|
85
|
-
described_class.stick_to_primary
|
|
86
|
-
|
|
87
|
-
stuck_inside = nil
|
|
88
|
-
executor.wrap { stuck_inside = described_class.use_primary? }
|
|
89
|
-
|
|
90
|
-
expect(stuck_inside).to be false
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it 'stops stickiness leaking from a previous run into the next' do
|
|
94
|
-
described_class.install_reset_hook(executor)
|
|
95
|
-
|
|
96
|
-
executor.wrap { described_class.stick_to_primary }
|
|
97
|
-
|
|
98
|
-
leaked = nil
|
|
99
|
-
executor.wrap { leaked = described_class.use_primary? }
|
|
100
|
-
expect(leaked).to be false
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'still starts the next run clean after the previous run raised' do
|
|
104
|
-
described_class.install_reset_hook(executor)
|
|
105
|
-
|
|
106
|
-
expect do
|
|
107
|
-
executor.wrap do
|
|
108
|
-
described_class.stick_to_primary
|
|
109
|
-
raise 'boom'
|
|
110
|
-
end
|
|
111
|
-
end.to raise_error('boom')
|
|
112
|
-
|
|
113
|
-
leaked = nil
|
|
114
|
-
executor.wrap { leaked = described_class.use_primary? }
|
|
115
|
-
expect(leaked).to be false
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'janus-ar/db_console_config'
|
|
4
|
-
|
|
5
|
-
RSpec.describe Janus::DbConsoleConfig do
|
|
6
|
-
subject(:console_config) { described_class.new(db_config) }
|
|
7
|
-
|
|
8
|
-
let(:db_config) do
|
|
9
|
-
instance_double(
|
|
10
|
-
ActiveRecord::DatabaseConfigurations::HashConfig,
|
|
11
|
-
configuration_hash: {
|
|
12
|
-
database: 'my_database',
|
|
13
|
-
janus: {
|
|
14
|
-
'primary' => { 'host' => 'primary.local', 'username' => 'primary' },
|
|
15
|
-
'replica' => { 'host' => 'replica.local', 'username' => 'replica' },
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it 'exposes the replica configuration with symbol keys so dbconsole connects to a replica' do
|
|
22
|
-
expect(console_config.configuration_hash).to eq(host: 'replica.local', username: 'replica')
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'exposes the database name from the top-level config' do
|
|
26
|
-
expect(console_config.database).to eq('my_database')
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Janus::Logging::Logger do
|
|
4
|
-
describe '.log' do
|
|
5
|
-
let(:logger) { double('logger') }
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
described_class.logger = logger
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it 'logs the message with the specified format' do
|
|
12
|
-
expect(logger).to receive(:send).with(:info, '[Janus] Test message')
|
|
13
|
-
described_class.log('Test message', :info)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'does not log the message if logger is not set' do
|
|
17
|
-
described_class.logger = nil
|
|
18
|
-
expect(logger).not_to receive(:send)
|
|
19
|
-
described_class.log('Test message', :info)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '.logger=' do
|
|
24
|
-
let(:logger) { double('logger') }
|
|
25
|
-
|
|
26
|
-
it 'sets the logger' do
|
|
27
|
-
described_class.logger = logger
|
|
28
|
-
expect(described_class.logger).to eq(logger)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|