janus-ar 8.0.0 → 8.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +142 -125
  4. data/README.md +153 -131
  5. data/janus-ar.gemspec +38 -36
  6. data/lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter.rb +32 -149
  7. data/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter.rb +32 -149
  8. data/lib/janus-ar/adapter_extensions.rb +112 -0
  9. data/lib/janus-ar/client.rb +6 -6
  10. data/lib/janus-ar/context.rb +79 -80
  11. data/lib/janus-ar/db_console_config.rb +17 -17
  12. data/lib/janus-ar/logging/logger.rb +15 -15
  13. data/lib/janus-ar/logging/subscriber.rb +27 -27
  14. data/lib/janus-ar/query_director.rb +87 -54
  15. data/lib/janus-ar/railtie.rb +15 -0
  16. data/lib/janus-ar/version.rb +17 -17
  17. data/lib/janus-ar.rb +24 -22
  18. metadata +10 -30
  19. data/.bundle/config +0 -5
  20. data/.github/dependabot.yml +0 -7
  21. data/.github/workflows/ci.yml +0 -60
  22. data/.github/workflows/publish.yml +0 -25
  23. data/.gitignore +0 -2
  24. data/.rspec +0 -3
  25. data/.rubocop.yml +0 -26
  26. data/assets/.gitkeep +0 -1
  27. data/assets/janus-logo.png +0 -0
  28. data/bin/release.sh +0 -3
  29. data/spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb +0 -82
  30. data/spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb +0 -82
  31. data/spec/lib/janus-ar/client_spec.rb +0 -7
  32. data/spec/lib/janus-ar/context_spec.rb +0 -46
  33. data/spec/lib/janus-ar/logging/logger_spec.rb +0 -31
  34. data/spec/lib/janus-ar/query_director_spec.rb +0 -59
  35. data/spec/shared_examples/a_mysql_like_server.rb +0 -85
  36. data/spec/spec_helper.rb +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 612d3c32af790b83f526dfe55c6a657e527c0d08c9dc7959c7203e5fe794fec0
4
- data.tar.gz: f98329224347cbe2e08a2fadef8d3e9e705afb281066a18aa29a7757fd0adf26
3
+ metadata.gz: cd05e24e1306fce67609a9e991fddad6c4d7014ce58f696a01eb64317838e837
4
+ data.tar.gz: d07db4e1d21a6363ed9f0f1ea41736b1d71d1ae0fd6c419f34f15e5f74e8825f
5
5
  SHA512:
6
- metadata.gz: 8565f506ef40bb85d1a453f3978961af94d3fcc0d4e743d691c443c656c4e2eaeb078c07e453abc7580fc7ff6e31184ca774fd90f6ffa33753d3de3c2646f4fe
7
- data.tar.gz: 653188ccf586dfd9d1d30bb666b62f09f053749a8b5b04c6403f05a5d6f02f8ae188c1d5eb1a00ee7944c9023cbd7796c482d2ac1c45e291af516d15abfe4b6c
6
+ metadata.gz: 9bc3a5029f1b51374051a2c6f8ccc743192780bae4eaaafe18ea6578d9fb77826760ae95a6714bb5ea8f3cd128ef51a3247d39416ae78b8af7b5554ee652ab64
7
+ data.tar.gz: 0fc71666876765b84cc70ddc4ffc016cd175ae8594fb68dd0a442b047a27aced86e5597ebb1fcf3cebc10d00e81081f8ff63122fcacc4eefa680a89c0fdc4ca2
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'http://rubygems.org'
3
+ source 'https://rubygems.org'
4
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,125 +1,142 @@
1
- PATH
2
- remote: .
3
- specs:
4
- janus-ar (7.2.0)
5
- activerecord (>= 8.0, < 9.0)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- activemodel (8.0.1)
11
- activesupport (= 8.0.1)
12
- activerecord (8.0.1)
13
- activemodel (= 8.0.1)
14
- activesupport (= 8.0.1)
15
- timeout (>= 0.4.0)
16
- activesupport (8.0.1)
17
- base64
18
- benchmark (>= 0.3)
19
- bigdecimal
20
- concurrent-ruby (~> 1.0, >= 1.3.1)
21
- connection_pool (>= 2.2.5)
22
- drb
23
- i18n (>= 1.6, < 2)
24
- logger (>= 1.4.2)
25
- minitest (>= 5.1)
26
- securerandom (>= 0.3)
27
- tzinfo (~> 2.0, >= 2.0.5)
28
- uri (>= 0.13.1)
29
- ast (2.4.2)
30
- base64 (0.2.0)
31
- benchmark (0.4.0)
32
- bigdecimal (3.1.9)
33
- coderay (1.1.3)
34
- concurrent-ruby (1.3.4)
35
- connection_pool (2.4.1)
36
- diff-lcs (1.5.1)
37
- drb (2.2.1)
38
- i18n (1.14.6)
39
- concurrent-ruby (~> 1.0)
40
- json (2.9.1)
41
- language_server-protocol (3.17.0.3)
42
- logger (1.6.4)
43
- method_source (1.1.0)
44
- minitest (5.25.4)
45
- mysql2 (0.5.6)
46
- parallel (1.26.3)
47
- parser (3.3.6.0)
48
- ast (~> 2.4.1)
49
- racc
50
- pry (0.15.2)
51
- coderay (~> 1.1)
52
- method_source (~> 1.0)
53
- racc (1.8.1)
54
- rack (3.1.8)
55
- rainbow (3.1.1)
56
- rake (13.2.1)
57
- regexp_parser (2.10.0)
58
- rspec (3.13.0)
59
- rspec-core (~> 3.13.0)
60
- rspec-expectations (~> 3.13.0)
61
- rspec-mocks (~> 3.13.0)
62
- rspec-core (3.13.0)
63
- rspec-support (~> 3.13.0)
64
- rspec-expectations (3.13.0)
65
- diff-lcs (>= 1.2.0, < 2.0)
66
- rspec-support (~> 3.13.0)
67
- rspec-mocks (3.13.0)
68
- diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.13.0)
70
- rspec-support (3.13.1)
71
- rubocop (1.69.2)
72
- json (~> 2.3)
73
- language_server-protocol (>= 3.17.0)
74
- parallel (~> 1.10)
75
- parser (>= 3.3.0.2)
76
- rainbow (>= 2.2.2, < 4.0)
77
- regexp_parser (>= 2.9.3, < 3.0)
78
- rubocop-ast (>= 1.36.2, < 2.0)
79
- ruby-progressbar (~> 1.7)
80
- unicode-display_width (>= 2.4.0, < 4.0)
81
- rubocop-ast (1.37.0)
82
- parser (>= 3.3.1.0)
83
- rubocop-performance (1.23.1)
84
- rubocop (>= 1.48.1, < 2.0)
85
- rubocop-ast (>= 1.31.1, < 2.0)
86
- rubocop-rails (2.28.0)
87
- activesupport (>= 4.2.0)
88
- rack (>= 1.1)
89
- rubocop (>= 1.52.0, < 2.0)
90
- rubocop-ast (>= 1.31.1, < 2.0)
91
- rubocop-rspec (3.2.0)
92
- rubocop (~> 1.61)
93
- rubocop-thread_safety (0.6.0)
94
- rubocop (>= 1.48.1)
95
- ruby-progressbar (1.13.0)
96
- securerandom (0.4.1)
97
- timeout (0.4.3)
98
- trilogy (2.9.0)
99
- tzinfo (2.0.6)
100
- concurrent-ruby (~> 1.0)
101
- unicode-display_width (3.1.3)
102
- unicode-emoji (~> 4.0, >= 4.0.4)
103
- unicode-emoji (4.0.4)
104
- uri (1.0.2)
105
-
106
- PLATFORMS
107
- arm64-darwin-23
108
- x86_64-linux
109
-
110
- DEPENDENCIES
111
- activesupport (>= 8.0)
112
- janus-ar!
113
- mysql2
114
- pry
115
- rake
116
- rspec (~> 3)
117
- rubocop (~> 1.69.2)
118
- rubocop-performance
119
- rubocop-rails (~> 2.28.0)
120
- rubocop-rspec
121
- rubocop-thread_safety
122
- trilogy
123
-
124
- BUNDLED WITH
125
- 2.4.22
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ janus-ar (8.1.0)
5
+ activerecord (>= 8.0, < 9.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (8.1.3.1)
11
+ activesupport (= 8.1.3.1)
12
+ activerecord (8.1.3.1)
13
+ activemodel (= 8.1.3.1)
14
+ activesupport (= 8.1.3.1)
15
+ timeout (>= 0.4.0)
16
+ activesupport (8.1.3.1)
17
+ base64
18
+ bigdecimal
19
+ concurrent-ruby (~> 1.0, >= 1.3.1)
20
+ connection_pool (>= 2.2.5)
21
+ drb
22
+ i18n (>= 1.6, < 2)
23
+ json
24
+ logger (>= 1.4.2)
25
+ minitest (>= 5.1)
26
+ securerandom (>= 0.3)
27
+ tzinfo (~> 2.0, >= 2.0.5)
28
+ uri (>= 0.13.1)
29
+ ast (2.4.3)
30
+ base64 (0.3.0)
31
+ bigdecimal (4.1.2)
32
+ coderay (1.1.3)
33
+ concurrent-ruby (1.3.8)
34
+ connection_pool (3.0.2)
35
+ diff-lcs (1.6.2)
36
+ drb (2.2.3)
37
+ i18n (1.15.2)
38
+ concurrent-ruby (~> 1.0)
39
+ io-console (0.8.2)
40
+ json (2.21.2)
41
+ language_server-protocol (3.17.0.6)
42
+ lint_roller (1.1.0)
43
+ logger (1.7.0)
44
+ method_source (1.1.0)
45
+ minitest (6.0.6)
46
+ drb (~> 2.0)
47
+ prism (~> 1.5)
48
+ mysql2 (0.5.7)
49
+ bigdecimal
50
+ parallel (1.28.0)
51
+ parser (3.3.12.0)
52
+ ast (~> 2.4.1)
53
+ racc
54
+ prism (1.9.0)
55
+ pry (0.16.0)
56
+ coderay (~> 1.1)
57
+ method_source (~> 1.0)
58
+ reline (>= 0.6.0)
59
+ racc (1.8.1)
60
+ rack (3.2.7)
61
+ rainbow (3.1.1)
62
+ rake (13.4.2)
63
+ regexp_parser (2.12.0)
64
+ reline (0.6.3)
65
+ io-console (~> 0.5)
66
+ rspec (3.13.2)
67
+ rspec-core (~> 3.13.0)
68
+ rspec-expectations (~> 3.13.0)
69
+ rspec-mocks (~> 3.13.0)
70
+ rspec-core (3.13.6)
71
+ rspec-support (~> 3.13.0)
72
+ rspec-expectations (3.13.5)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.13.0)
75
+ rspec-mocks (3.13.7)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.13.0)
78
+ rspec-support (3.13.7)
79
+ rubocop (1.90.0)
80
+ json (>= 2.3)
81
+ language_server-protocol (~> 3.17.0.2)
82
+ lint_roller (~> 1.1.0)
83
+ parallel (>= 1.10)
84
+ parser (>= 3.3.0.2)
85
+ rainbow (>= 2.2.2, < 4.0)
86
+ regexp_parser (>= 2.9.3, < 3.0)
87
+ rubocop-ast (>= 1.49.0, < 2.0)
88
+ ruby-progressbar (~> 1.7)
89
+ unicode-display_width (>= 2.4.0, < 4.0)
90
+ rubocop-ast (1.50.0)
91
+ parser (>= 3.3.7.2)
92
+ prism (~> 1.7)
93
+ rubocop-performance (1.27.0)
94
+ lint_roller (~> 1.1)
95
+ rubocop (>= 1.89.0, < 2.0)
96
+ rubocop-ast (>= 1.47.1, < 2.0)
97
+ rubocop-rails (2.37.0)
98
+ activesupport (>= 4.2.0)
99
+ lint_roller (~> 1.1)
100
+ rack (>= 1.1)
101
+ rubocop (>= 1.89.0, < 2.0)
102
+ rubocop-ast (>= 1.44.0, < 2.0)
103
+ rubocop-rspec (3.10.2)
104
+ lint_roller (~> 1.1)
105
+ regexp_parser (>= 2.0)
106
+ rubocop (~> 1.86, >= 1.86.2)
107
+ rubocop-thread_safety (0.7.3)
108
+ lint_roller (~> 1.1)
109
+ rubocop (~> 1.72, >= 1.72.1)
110
+ rubocop-ast (>= 1.44.0, < 2.0)
111
+ ruby-progressbar (1.13.0)
112
+ securerandom (0.4.1)
113
+ timeout (0.6.1)
114
+ trilogy (2.13.0)
115
+ bigdecimal
116
+ tzinfo (2.0.6)
117
+ concurrent-ruby (~> 1.0)
118
+ unicode-display_width (3.2.0)
119
+ unicode-emoji (~> 4.1)
120
+ unicode-emoji (4.2.0)
121
+ uri (1.1.1)
122
+
123
+ PLATFORMS
124
+ arm64-darwin-23
125
+ x86_64-linux
126
+
127
+ DEPENDENCIES
128
+ activesupport (>= 8.0)
129
+ janus-ar!
130
+ mysql2
131
+ pry
132
+ rake
133
+ rspec (~> 3)
134
+ rubocop (~> 1.90.0)
135
+ rubocop-performance
136
+ rubocop-rails (~> 2.37.0)
137
+ rubocop-rspec
138
+ rubocop-thread_safety
139
+ trilogy
140
+
141
+ BUNDLED WITH
142
+ 2.4.22
data/README.md CHANGED
@@ -1,131 +1,153 @@
1
- # Janus ActiveRecord
2
-
3
- <p align="center">
4
- <img src="assets/janus-logo.png"
5
- alt="Janus Logo"
6
- style="float: left; margin: 0 auto; height: 500px;" />
7
- </p>
8
-
9
- > In ancient Roman religion and myth, Janus (/ˈdʒeɪnəs/ JAY-nəs; Latin: Ianvs [ˈi̯aːnʊs]) is the god of beginnings, gates, transitions, time, duality, doorways,[2] passages, frames, and endings. [(wikipedia)](https://en.wikipedia.org/wiki/Janus)
10
-
11
- [![CI](https://github.com/OLIOEX/janus-ar/actions/workflows/ci.yml/badge.svg)](https://github.com/OLIOEX/janus-ar/actions/workflows/ci.yml)
12
- [![Gem Version](https://badge.fury.io/rb/janus-ar.svg)](https://badge.fury.io/rb/janus-ar)
13
-
14
- Janus ActiveRecord is generic primary/replica proxy for ActiveRecord 7.1+ and MySQL (via `mysql2` and `trilogy`). It handles the switching of connections between primary and replica database servers. It comes with an ActiveRecord database adapter implementation.
15
-
16
- Note: Trilogy support is experimental at this stage.
17
-
18
- Janus is heavily inspired by [Makara](https://github.com/instacart/makara) from TaskRabbit and then Instacart. Unfortunately this project is unmaintained and broke for us with Rails 7.1. This is an attempt to start afresh on the project. It is definitely not as fully featured as Makara at this stage.
19
-
20
- Learn more about its origins: [https://tech.olioex.com/ruby/2024/04/16/introducing-janus.html](https://tech.olioex.com/ruby/2024/04/16/introducing-janus.html).
21
-
22
- Notes: GEM is currently tested with MySQL 8, Ruby 3.2, ActiveRecord 7.1+
23
-
24
- ## Installation
25
-
26
- Use the current version of the gem from [rubygems](https://rubygems.org/gems/janus-ar) in your `Gemfile`.
27
-
28
- ```ruby
29
- gem 'janus-ar'
30
- ```
31
-
32
- This project assumes that your read/write endpoints are handled by a separate system (e.g. DNS).
33
-
34
- ## Usage
35
-
36
- After a write request during a thread the adapter will continue using the `primary` server, unless the context is specifically released.
37
-
38
- ### Setup
39
-
40
- #### Rails 7.2+
41
-
42
- For Rails 7.2 you'll need to manually register the database adaptor in `config/application.rb` after requiring rails but before entering the application configuration, e.g.
43
-
44
- ```ruby
45
- require 'rails/all'
46
-
47
- ActiveRecord::ConnectionAdapters.register("janus_trilogy", "ActiveRecord::ConnectionAdapters::JanusTrilogyAdapter", 'janus-ar/active_record/connection_adapters/janus_trilogy_adapter')
48
- # ...or...
49
- ActiveRecord::ConnectionAdapters.register("janus_mysql2", "ActiveRecord::ConnectionAdapters::JanusMysql2Adapter", 'janus-ar/active_record/connection_adapters/janus_mysql2_adapter')
50
- ```
51
-
52
- #### Rails <= 7.1
53
-
54
- ActiveRecord 7.1 was tested up to releases v0.15.*. After this release we only tested Rails 7.2+. This does not mean it is not compatible, just not tested.
55
-
56
- ### Configuration
57
-
58
- Update your **database.yml** as follows:
59
-
60
- ```yml
61
- development:
62
- adapter: janus_mysql2
63
- database: database_name
64
- janus:
65
- primary:
66
- <<: *default
67
- host: primary-host.local
68
- replica:
69
- <<: *default
70
- password: ithappenstobedifferent
71
- host: replica-host.local
72
- ```
73
- Note: For `trilogy` please use adapter "janus_trilogy". You'll probably need to add the following to your configuration to have it connect:
74
-
75
- ```yml
76
- ssl: true
77
- ssl_mode: 'REQUIRED'
78
- tls_min_version: 3
79
- ```
80
-
81
- `tls_min_version` here refers to TLS1.2.
82
-
83
- Otherwise you will get an error like the following (see https://github.com/trilogy-libraries/trilogy/issues/26):
84
- > trilogy_auth_recv: caching_sha2_password requires either TCP with TLS or a unix socket: TRILOGY_UNSUPPORTED"
85
-
86
- ### Forcing connections
87
-
88
- A context is local to the curent thread of execution. This will allow you to stick to the primary safely in a single thread
89
- in systems such as sidekiq, for instance.
90
-
91
- #### Releasing stuck connections (clearing context)
92
-
93
- If you need to clear the current context, releasing any stuck connections, all you have to do is:
94
-
95
- ```ruby
96
- Janus::Context.release_all
97
- ```
98
-
99
- #### Forcing connection to primary server
100
-
101
- ```ruby
102
- Janus::Context.stick_to_primary
103
- ```
104
-
105
- ### Logging
106
-
107
- You can set a logger instance to `::Janus::Logging::Logger.logger`:
108
-
109
- ```ruby
110
- Janus::Logging::Logger.logger = ::Logger.new(STDOUT)
111
- ```
112
-
113
- If using `ActiveRecord` logging, Janus will append the name of the connection used to any logs e.g. `[primary]` or `[replica]`.
114
-
115
- ### What queries goes where?
116
-
117
- In general: Any `SELECT` statements will execute against your replica(s), anything else will go to the primary.
118
-
119
- There are some edge cases:
120
- * `SET` operations will be sent to all connections
121
- * Execution of specific methods such as `connect!`, `disconnect!`, `reconnect!`, and `clear_cache!` are invoked on all underlying connections
122
- * Calls inside a transaction will always be sent to the primary (otherwise changes from within the transaction could not be read back on most transaction isolation levels)
123
- * Locking reads (e.g. `SELECT ... FOR UPDATE`) will always be sent to the primary
124
-
125
- # Notes
126
-
127
- Janus does not support Rails' read/write split or sharding using `with_connection`.
128
-
129
- # Acknowlegements
130
-
131
- Amazing project logo by @undevelopedbruce.
1
+ # Janus ActiveRecord
2
+
3
+ <p align="center">
4
+ <img src="assets/janus-logo.png"
5
+ alt="Janus Logo"
6
+ style="float: left; margin: 0 auto; height: 500px;" />
7
+ </p>
8
+
9
+ > In ancient Roman religion and myth, Janus (/ˈdʒeɪnəs/ JAY-nəs; Latin: Ianvs [ˈi̯aːnʊs]) is the god of beginnings, gates, transitions, time, duality, doorways,[2] passages, frames, and endings. [(wikipedia)](https://en.wikipedia.org/wiki/Janus)
10
+
11
+ [![CI](https://github.com/OLIOEX/janus-ar/actions/workflows/ci.yml/badge.svg)](https://github.com/OLIOEX/janus-ar/actions/workflows/ci.yml)
12
+ [![Gem Version](https://badge.fury.io/rb/janus-ar.svg)](https://badge.fury.io/rb/janus-ar)
13
+
14
+ Janus ActiveRecord is a generic primary/replica proxy for ActiveRecord 8 and MySQL (via `mysql2` and `trilogy`). It handles the switching of connections between primary and replica database servers. It comes with an ActiveRecord database adapter implementation.
15
+
16
+ Janus is heavily inspired by [Makara](https://github.com/instacart/makara) from TaskRabbit and then Instacart. Unfortunately this project is unmaintained and broke for us with Rails 7.1. This is an attempt to start afresh on the project. It is definitely not as fully featured as Makara at this stage.
17
+
18
+ Learn more about its origins: [https://tech.olioex.com/ruby/2024/04/16/introducing-janus.html](https://tech.olioex.com/ruby/2024/04/16/introducing-janus.html).
19
+
20
+ Notes: the gem requires ActiveRecord `>= 8.0, < 9.0` and Ruby `>= 3.2`, and is tested against MySQL 8.
21
+
22
+ ## Installation
23
+
24
+ Use the current version of the gem from [rubygems](https://rubygems.org/gems/janus-ar) in your `Gemfile`.
25
+
26
+ ```ruby
27
+ gem 'janus-ar'
28
+ ```
29
+
30
+ This project assumes that your read/write endpoints are handled by a separate system (e.g. DNS).
31
+
32
+ ## Usage
33
+
34
+ After a write request during a thread the adapter will continue using the `primary` server, unless the context is specifically released.
35
+
36
+ ### Setup
37
+
38
+ #### Rails 7.2+
39
+
40
+ For Rails 7.2 you'll need to manually register the database adaptor in `config/application.rb` after requiring rails but before entering the application configuration, e.g.
41
+
42
+ ```ruby
43
+ require 'rails/all'
44
+
45
+ ActiveRecord::ConnectionAdapters.register("janus_trilogy", "ActiveRecord::ConnectionAdapters::JanusTrilogyAdapter", 'janus-ar/active_record/connection_adapters/janus_trilogy_adapter')
46
+ # ...or...
47
+ ActiveRecord::ConnectionAdapters.register("janus_mysql2", "ActiveRecord::ConnectionAdapters::JanusMysql2Adapter", 'janus-ar/active_record/connection_adapters/janus_mysql2_adapter')
48
+ ```
49
+
50
+ #### Rails <= 7.1
51
+
52
+ ActiveRecord 7.1 was tested up to releases v0.15.*. After this release we only tested Rails 7.2+. This does not mean it is not compatible, just not tested.
53
+
54
+ ### Configuration
55
+
56
+ Update your **database.yml** as follows:
57
+
58
+ ```yml
59
+ development:
60
+ adapter: janus_mysql2
61
+ database: database_name
62
+ janus:
63
+ primary:
64
+ <<: *default
65
+ host: primary-host.local
66
+ replica:
67
+ <<: *default
68
+ password: ithappenstobedifferent
69
+ host: replica-host.local
70
+ ```
71
+ Note: For `trilogy` please use adapter "janus_trilogy". You'll probably need to add the following to your configuration to have it connect:
72
+
73
+ ```yml
74
+ ssl: true
75
+ ssl_mode: 'REQUIRED'
76
+ tls_min_version: 3
77
+ ```
78
+
79
+ `tls_min_version` here refers to TLS1.2.
80
+
81
+ Otherwise you will get an error like the following (see https://github.com/trilogy-libraries/trilogy/issues/26):
82
+ > trilogy_auth_recv: caching_sha2_password requires either TCP with TLS or a unix socket: TRILOGY_UNSUPPORTED"
83
+
84
+ ### Forcing connections
85
+
86
+ A context is local to the current unit of work (thread or fiber, following ActiveRecord's configured isolation level). This allows you to stick to the primary safely within a single request or job, in systems such as Sidekiq for instance.
87
+
88
+ #### Releasing stuck connections (clearing context)
89
+
90
+ In a Rails application the context is released automatically at the start of every unit of work wrapped by the Rails executor — web requests, ActiveJob and Sidekiq-on-Rails jobs — so stickiness from a write never leaks into the next request on a reused thread. You do not need to do anything for this.
91
+
92
+ Outside of Rails (or to clear the context manually), call:
93
+
94
+ ```ruby
95
+ Janus::Context.release_all
96
+ ```
97
+
98
+ #### Forcing connection to primary server
99
+
100
+ ```ruby
101
+ Janus::Context.stick_to_primary
102
+ ```
103
+
104
+ ### Logging
105
+
106
+ You can set a logger instance to `::Janus::Logging::Logger.logger`:
107
+
108
+ ```ruby
109
+ Janus::Logging::Logger.logger = ::Logger.new(STDOUT)
110
+ ```
111
+
112
+ If using `ActiveRecord` logging, Janus will append the name of the connection used to any logs e.g. `[primary]` or `[replica]`.
113
+
114
+ ### What queries goes where?
115
+
116
+ In general: Any `SELECT` statements will execute against your replica(s), anything else will go to the primary.
117
+
118
+ There are some edge cases:
119
+ * `SET` operations will be sent to all connections
120
+ * Execution of specific methods such as `connect!`, `disconnect!`, `reconnect!`, and `clear_cache!` are invoked on all underlying connections
121
+ * Calls inside a transaction will always be sent to the primary (otherwise changes from within the transaction could not be read back on most transaction isolation levels)
122
+ * Locking reads (e.g. `SELECT ... FOR UPDATE`, `FOR UPDATE SKIP LOCKED`, `FOR SHARE`, `LOCK IN SHARE MODE`, `GET_LOCK(...)`) will always be sent to the primary
123
+
124
+ # Notes
125
+
126
+ Janus does not support Rails' read/write split or sharding using `with_connection`.
127
+
128
+ # Acknowlegements
129
+
130
+ Amazing project logo by @undevelopedbruce.
131
+
132
+ ## Releasing
133
+
134
+ Releases are cut from the [GitHub Releases UI](https://github.com/OLIOEX/janus-ar/releases/new).
135
+ Publishing to RubyGems is automatic — there is nothing to bump by hand, and no
136
+ API key to rotate (authentication uses RubyGems
137
+ [trusted publishing](https://guides.rubygems.org/trusted-publishing/) over OIDC).
138
+
139
+ To release:
140
+
141
+ 1. Create a new release against the head of `main`, with a tag named
142
+ `vMAJOR.MINOR.PATCH` — e.g. `v8.1.0`. Pre-release suffixes use a dot, as
143
+ RubyGems requires: `v8.1.0.rc1`, not `v8.1.0-rc1`.
144
+ 2. Publish it.
145
+
146
+ [`.github/workflows/publish.yml`](.github/workflows/publish.yml) then takes the
147
+ version from the tag, writes it into `lib/janus-ar/version.rb`, refreshes
148
+ `Gemfile.lock`, commits that bump to `main` as `Release vX.Y.Z`, moves the tag
149
+ onto that commit, and pushes the gem.
150
+
151
+ Because the bump is committed to `main`, releases must be created from its head
152
+ — the workflow refuses to publish if the tag sits anywhere else. You never need
153
+ to edit `version.rb` yourself; the tag is the source of truth.