makara 0.4.1 → 0.5.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 +5 -5
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/CI.yml +88 -0
- data/.github/workflows/gem-publish-public.yml +36 -0
- data/.rspec +1 -1
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +670 -0
- data/CHANGELOG.md +69 -48
- data/Gemfile +1 -16
- data/README.md +8 -9
- data/Rakefile +1 -1
- data/gemfiles/activerecord_5.2.gemfile +8 -0
- data/gemfiles/activerecord_6.0.gemfile +8 -0
- data/gemfiles/activerecord_6.1.gemfile +8 -0
- data/gemfiles/activerecord_head.gemfile +6 -0
- data/lib/active_record/connection_adapters/jdbcmysql_makara_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/jdbcpostgresql_makara_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +107 -30
- data/lib/active_record/connection_adapters/makara_jdbcmysql_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_jdbcpostgresql_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_mysql2_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/makara_postgis_adapter.rb +4 -19
- data/lib/active_record/connection_adapters/makara_postgresql_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/mysql2_makara_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/postgresql_makara_adapter.rb +4 -20
- data/lib/makara/cache.rb +0 -2
- data/lib/makara/config_parser.rb +7 -15
- data/lib/makara/connection_wrapper.rb +43 -22
- data/lib/makara/context.rb +1 -0
- data/lib/makara/cookie.rb +1 -0
- data/lib/makara/error_handler.rb +0 -9
- data/lib/makara/errors/all_connections_blacklisted.rb +0 -2
- data/lib/makara/errors/blacklist_connection.rb +0 -2
- data/lib/makara/errors/blacklisted_while_in_transaction.rb +12 -0
- data/lib/makara/errors/invalid_shard.rb +14 -0
- data/lib/makara/errors/makara_error.rb +0 -1
- data/lib/makara/errors/no_connections_available.rb +0 -2
- data/lib/makara/logging/logger.rb +0 -4
- data/lib/makara/logging/subscriber.rb +0 -2
- data/lib/makara/middleware.rb +1 -2
- data/lib/makara/pool.rb +49 -31
- data/lib/makara/proxy.rb +56 -30
- data/lib/makara/railtie.rb +0 -2
- data/lib/makara/strategies/abstract.rb +1 -0
- data/lib/makara/strategies/priority_failover.rb +2 -0
- data/lib/makara/strategies/round_robin.rb +1 -3
- data/lib/makara/strategies/shard_aware.rb +45 -0
- data/lib/makara/version.rb +1 -3
- data/lib/makara.rb +7 -6
- data/makara.gemspec +26 -3
- data/spec/active_record/connection_adapters/makara_abstract_adapter_error_handling_spec.rb +1 -6
- data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +0 -9
- data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +9 -22
- data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +2 -10
- data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +62 -18
- data/spec/cache_spec.rb +0 -1
- data/spec/config_parser_spec.rb +54 -56
- data/spec/connection_wrapper_spec.rb +1 -2
- data/spec/cookie_spec.rb +4 -4
- data/spec/middleware_spec.rb +2 -2
- data/spec/pool_spec.rb +25 -14
- data/spec/proxy_spec.rb +0 -4
- data/spec/spec_helper.rb +6 -1
- data/spec/strategies/priority_failover_spec.rb +3 -4
- data/spec/strategies/round_robin_spec.rb +4 -8
- data/spec/strategies/shard_aware_spec.rb +218 -0
- data/spec/support/deep_dup.rb +1 -1
- data/spec/support/helpers.rb +5 -5
- data/spec/support/mock_objects.rb +5 -4
- data/spec/support/mysql2_database.yml +2 -2
- data/spec/support/mysql2_database_with_custom_errors.yml +2 -2
- data/spec/support/pool_extensions.rb +0 -3
- data/spec/support/postgis_schema.rb +1 -1
- data/spec/support/postgresql_database.yml +0 -2
- data/spec/support/proxy_extensions.rb +1 -3
- data/spec/support/schema.rb +1 -1
- data/spec/support/user.rb +1 -2
- metadata +165 -20
- data/.travis.yml +0 -105
- data/gemfiles/ar-head.gemfile +0 -24
- data/gemfiles/ar30.gemfile +0 -36
- data/gemfiles/ar31.gemfile +0 -36
- data/gemfiles/ar32.gemfile +0 -36
- data/gemfiles/ar40.gemfile +0 -24
- data/gemfiles/ar41.gemfile +0 -24
- data/gemfiles/ar42.gemfile +0 -24
- data/gemfiles/ar50.gemfile +0 -24
- data/gemfiles/ar51.gemfile +0 -24
data/CHANGELOG.md
CHANGED
@@ -1,109 +1,130 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## Unreleased
|
5
|
+
|
6
|
+
### v0.5.1 - 2021-06-04
|
7
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.5.0...v0.6.0.pre)
|
8
|
+
- Use ActiveRecord URL resolver instead of copying definition [#294](https://github.com/instacart/makara/pull/294) Matt Larraz
|
9
|
+
- Fix Ruby 2.7 kwarg warning and add Ruby 3 support [#283](https://github.com/instacart/makara/pull/283) Matt Larraz
|
10
|
+
- Drop support for Ruby < 2.5 and ActiveRecord < 5.2 [#281](https://github.com/instacart/makara/pull/281) Matt Larraz
|
11
|
+
|
12
|
+
## v0.5.0 - 2021-01-08
|
13
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.4.1...v0.4.2)
|
14
|
+
- Replace deprecated URI.unescape with CGI.unescape [#252](https://github.com/instacart/makara/pull/252) Kevin Robatel
|
15
|
+
- Override equality operator for ActiveRecord connection wrapper [#269](https://github.com/instacart/makara/pull/269) Praveen Burgu
|
16
|
+
- Handle blacklisted connections in master pool while in transaction [#267](https://github.com/instacart/makara/pull/267) Praveen Burgu
|
17
|
+
- Handle ActiveRecord connection pools correctly [#267](https://github.com/instacart/makara/pull/267) Praveen Burgu
|
18
|
+
- Add preliminary support for sharded databases [#267](https://github.com/instacart/makara/pull/267) Praveen Burgu
|
19
|
+
- Fix ActiveRecord connection pool exhaustion [#268](https://github.com/instacart/makara/pull/268) Praveen Burgu
|
20
|
+
- Drop support for Ruby 2.0, 2.1 and 2.2 [#267](https://github.com/instacart/makara/pull/267) Praveen Burgu
|
21
|
+
- Drop support ActiveRecord 3.x and 4.x [#267](https://github.com/instacart/makara/pull/267) Praveen Burgu
|
22
|
+
- Set up automatic publishing to Github and Rubygems [#275](https://github.com/instacart/makara/pull/275) Matt Larraz
|
23
|
+
|
24
|
+
|
4
25
|
## v0.4.1 - 2019-03-25
|
5
|
-
[Full Changelog](https://github.com/
|
26
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.4.0...v0.4.1)
|
6
27
|
|
7
|
-
- Fix crash by requiring makara in the adapter [#54](https://github.com/
|
8
|
-
- Add connection logging in non-Rails enviroments [#223](https://github.com/
|
28
|
+
- Fix crash by requiring makara in the adapter [#54](https://github.com/instacart/makara/pull/54) Eric Saxby
|
29
|
+
- Add connection logging in non-Rails enviroments [#223](https://github.com/instacart/makara/pull/223) Andrew Kane
|
9
30
|
|
10
31
|
## v0.4.0 - 2018-04-01
|
11
|
-
[Full Changelog](https://github.com/
|
32
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.10...v0.4.0)
|
12
33
|
|
13
34
|
This release is a major change to how we remember state between requests. A redis store is no longer needed. Everything is in the cookies.
|
14
|
-
- Implement stickiness for the duration of `master_ttl` via cookies [#194](https://github.com/
|
35
|
+
- Implement stickiness for the duration of `master_ttl` via cookies [#194](https://github.com/instacart/makara/pull/194) Rosa Gutierrez
|
15
36
|
|
16
37
|
|
17
38
|
## v0.3.10 - 2018-03-20
|
18
|
-
[Full Changelog](https://github.com/
|
39
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.9...v0.3.10)
|
19
40
|
|
20
41
|
Fixed
|
21
|
-
- Send nextval queries to master and show queries to replicas for Postgres [#173](https://github.com/
|
22
|
-
- Fixes can't add a new key into hash during iteration error [#174](https://github.com/
|
23
|
-
- Fix: an application freezes when a slave is down [#180](https://github.com/
|
24
|
-
- Allow SELECTs that use common table expressions to go to replicas [#184](https://github.com/
|
25
|
-
- Send advisory lock requests to the master [#198](https://github.com/
|
26
|
-
- Postgres exists query [#199](https://github.com/
|
42
|
+
- Send nextval queries to master and show queries to replicas for Postgres [#173](https://github.com/instacart/makara/pull/173) Andrew Kane
|
43
|
+
- Fixes can't add a new key into hash during iteration error [#174](https://github.com/instacart/makara/pull/174) Andrew Kane
|
44
|
+
- Fix: an application freezes when a slave is down [#180](https://github.com/instacart/makara/pull/180) Alexey P
|
45
|
+
- Allow SELECTs that use common table expressions to go to replicas [#184](https://github.com/instacart/makara/pull/184) Andrew Kane
|
46
|
+
- Send advisory lock requests to the master [#198](https://github.com/instacart/makara/pull/198) George Claghorn
|
47
|
+
- Postgres exists query [#199](https://github.com/instacart/makara/pull/199) Brian Leonard
|
27
48
|
|
28
49
|
Documentation and Test
|
29
|
-
- Clarify README's "What goes where" [#187](https://github.com/
|
30
|
-
- Fix loading fixtures in Rails 5.2 [#192](https://github.com/
|
31
|
-
- Travis Upgrade [#199](https://github.com/
|
50
|
+
- Clarify README's "What goes where" [#187](https://github.com/instacart/makara/pull/187) Jan Sandbrink
|
51
|
+
- Fix loading fixtures in Rails 5.2 [#192](https://github.com/instacart/makara/pull/192) George Claghorn
|
52
|
+
- Travis Upgrade [#199](https://github.com/instacart/makara/pull/199) Brian Leonard
|
32
53
|
|
33
54
|
## v0.3.9 - 2017-08-14
|
34
|
-
[Full Changelog](https://github.com/
|
55
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.8...v0.3.9)
|
35
56
|
|
36
57
|
Changed
|
37
|
-
- Add postgis support [#118](https://github.com/
|
58
|
+
- Add postgis support [#118](https://github.com/instacart/makara/pull/118) Kevin Bacha
|
38
59
|
|
39
60
|
## v0.3.8 - 2017-07-11
|
40
61
|
|
41
|
-
[Full Changelog](https://github.com/
|
62
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.7...v0.3.8)
|
42
63
|
|
43
64
|
Changed
|
44
|
-
- Rails 5.1 compatibility [#150](https://github.com/
|
45
|
-
- Minimize redundant context cache requests [#157](https://github.com/
|
46
|
-
- thread-local cache for previous context stickiness [#158](https://github.com/
|
47
|
-
- Configurable cookie options [#159](https://github.com/
|
48
|
-
- Test against Rails 5.x and Ruby 2.x [#160](https://github.com/
|
65
|
+
- Rails 5.1 compatibility [#150](https://github.com/instacart/makara/pull/150) Jeremy Daer
|
66
|
+
- Minimize redundant context cache requests [#157](https://github.com/instacart/makara/issues/157) Greg Patrick
|
67
|
+
- thread-local cache for previous context stickiness [#158](https://github.com/instacart/makara/issues/158) Jeremy Daer
|
68
|
+
- Configurable cookie options [#159](https://github.com/instacart/makara/pull/159) Jeremy Daer
|
69
|
+
- Test against Rails 5.x and Ruby 2.x [#160](https://github.com/instacart/makara/pull/160) Jeremy Daer
|
49
70
|
|
50
71
|
## v0.3.7 - 2016-09-22
|
51
72
|
|
52
|
-
[Full Changelog](https://github.com/
|
73
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.6...v0.3.7)
|
53
74
|
|
54
75
|
Changed
|
55
76
|
|
56
|
-
- Fix the hierarchy of the config file [#116](https://github.com/
|
57
|
-
- "Disable blacklist" parameter [#134](https://github.com/
|
58
|
-
- Fixes bug in `without_sticking` [#96](https://github.com/
|
59
|
-
- Always stick inside transactions [#96](https://github.com/
|
60
|
-
- Rails 5 support [#122](https://github.com/
|
77
|
+
- Fix the hierarchy of the config file [#116](https://github.com/instacart/makara/pull/116) Kevin Bacha
|
78
|
+
- "Disable blacklist" parameter [#134](https://github.com/instacart/makara/pull/134) Alex Tonkonozhenko
|
79
|
+
- Fixes bug in `without_sticking` [#96](https://github.com/instacart/makara/pull/96) Brian Leonard
|
80
|
+
- Always stick inside transactions [#96](https://github.com/instacart/makara/pull/96) Brian Leonard
|
81
|
+
- Rails 5 support [#122](https://github.com/instacart/makara/pull/122) Jonny McAllister
|
61
82
|
|
62
83
|
## v0.3.6 - 2016-04-21
|
63
84
|
|
64
|
-
[Full Changelog](https://github.com/
|
85
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.5...v0.3.6)
|
65
86
|
|
66
87
|
Changed
|
67
88
|
|
68
|
-
- Allow different strategies such as `priority` and `round_robin` for pools [#105](https://github.com/
|
89
|
+
- Allow different strategies such as `priority` and `round_robin` for pools [#105](https://github.com/instacart/makara/pull/105) Brian Leonard
|
69
90
|
|
70
91
|
|
71
92
|
## v0.3.5 - 2016-01-08
|
72
93
|
|
73
|
-
[Full Changelog](https://github.com/
|
94
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.4.rc1...v0.3.5)
|
74
95
|
|
75
96
|
Changed
|
76
97
|
|
77
|
-
- Raise `Makara::Errors::AllConnectionsBlacklisted` on timeout. [#104](https://github.com/
|
98
|
+
- Raise `Makara::Errors::AllConnectionsBlacklisted` on timeout. [#104](https://github.com/instacart/makara/pull/104) Brian Leonard
|
78
99
|
|
79
100
|
## v0.3.4.rc1 - 2016-01-06
|
80
101
|
|
81
|
-
[Full Changelog](https://github.com/
|
102
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.3...v0.3.4.rc1)
|
82
103
|
|
83
104
|
Added
|
84
105
|
|
85
|
-
- Add `url` to database connections configurations. [#93](https://github.com/
|
106
|
+
- Add `url` to database connections configurations. [#93](https://github.com/instacart/makara/pull/93) Benjamin Fleischer
|
86
107
|
|
87
108
|
Changed
|
88
109
|
|
89
|
-
- Improve Postgresql compatibility and failover support, also fix [#78](https://github.com/
|
90
|
-
- Update README: Specify newrelic_rpm gem versions that will have the performance issue. [#95](https://github.com/
|
110
|
+
- Improve Postgresql compatibility and failover support, also fix [#78](https://github.com/instacart/makara/issues/78), [#79](https://github.com/instacart/makara/issues/79). [#87](https://github.com/instacart/makara/pull/87) Vlad
|
111
|
+
- Update README: Specify newrelic_rpm gem versions that will have the performance issue. [#95](https://github.com/instacart/makara/pull/95) Benjamin Fleischer
|
91
112
|
|
92
113
|
## v0.3.3 - 2015-05-20
|
93
114
|
|
94
|
-
[Full Changelog](https://github.com/
|
115
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.2...v0.3.3)
|
95
116
|
|
96
117
|
Changed
|
97
118
|
|
98
|
-
- A context is local to the curent thread of execution. This will allow you to stick to master safely in a single thread in systems such as sidekiq, for instance. Fix [#83](https://github.com/
|
119
|
+
- A context is local to the curent thread of execution. This will allow you to stick to master safely in a single thread in systems such as sidekiq, for instance. Fix [#83](https://github.com/instacart/makara/issues/83). [#84](https://github.com/instacart/makara/pull/84) Matt Camuto
|
99
120
|
|
100
121
|
## v0.3.2 - 2015-05-16
|
101
122
|
|
102
|
-
[Full Changelog](https://github.com/
|
123
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.1...v0.3.2)
|
103
124
|
|
104
125
|
Fixed
|
105
126
|
|
106
|
-
- Fix a `ArgumentError: not delegated` error for rails 3. [#82](https://github.com/
|
127
|
+
- Fix a `ArgumentError: not delegated` error for rails 3. [#82](https://github.com/instacart/makara/pull/82) Eric Saxby
|
107
128
|
|
108
129
|
Changed
|
109
130
|
|
@@ -111,7 +132,7 @@ Changed
|
|
111
132
|
|
112
133
|
## v0.3.1 - 2015-05-08
|
113
134
|
|
114
|
-
[Full Changelog](https://github.com/
|
135
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.0...v0.3.1)
|
115
136
|
|
116
137
|
Changed
|
117
138
|
|
@@ -121,21 +142,21 @@ Changed
|
|
121
142
|
|
122
143
|
## v0.3.0 - 2015-04-27
|
123
144
|
|
124
|
-
[Full Changelog](https://github.com/
|
145
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.0.rc3...v0.3.0)
|
125
146
|
|
126
147
|
Changed
|
127
148
|
|
128
|
-
- Reduce logging noise by using [the same rules as ActiveRecord uses](https://github.com/rails/rails/blob/b06f64c3480cd389d14618540d62da4978918af0/activerecord/lib/active_record/log_subscriber.rb#L33). [#76](https://github.com/
|
149
|
+
- Reduce logging noise by using [the same rules as ActiveRecord uses](https://github.com/rails/rails/blob/b06f64c3480cd389d14618540d62da4978918af0/activerecord/lib/active_record/log_subscriber.rb#L33). [#76](https://github.com/instacart/makara/pull/76) Andrew Kane
|
129
150
|
|
130
151
|
Fixed
|
131
152
|
|
132
|
-
- Fix an issue for postgres that would route all queries to master. [#72](https://github.com/
|
133
|
-
- Fix an edge case which would cause SET operations to send to all connections([#70](https://github.com/
|
134
|
-
- Fix performance regression with certain verions of [newrelic/rpm](https://github.com/newrelic/rpm)([#59](https://github.com/
|
153
|
+
- Fix an issue for postgres that would route all queries to master. [#72](https://github.com/instacart/makara/pull/72) Kali Donovan
|
154
|
+
- Fix an edge case which would cause SET operations to send to all connections([#70](https://github.com/instacart/makara/issues/70)). [#80](https://github.com/instacart/makara/pull/80) Michael Amor Righi
|
155
|
+
- Fix performance regression with certain verions of [newrelic/rpm](https://github.com/newrelic/rpm)([#59](https://github.com/instacart/makara/issues/59)). [#75](https://github.com/instacart/makara/pull/75) Mike Nelson
|
135
156
|
|
136
157
|
## 0.3.0.rc3 - 2014-09-02[YANKED]
|
137
158
|
|
138
|
-
[Full Changelog](https://github.com/
|
159
|
+
[Full Changelog](https://github.com/instacart/makara/compare/v0.3.0.rc2...v0.3.0.rc3)
|
139
160
|
|
140
161
|
Added
|
141
162
|
- Allow bypassing of stickiness
|
data/Gemfile
CHANGED
@@ -1,19 +1,4 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in makara.gemspec
|
4
4
|
gemspec
|
5
|
-
|
6
|
-
gem 'rake'
|
7
|
-
gem 'rspec'
|
8
|
-
gem 'timecop'
|
9
|
-
gem 'byebug', :platform => :ruby
|
10
|
-
gem 'ruby-debug', :platform => :jruby
|
11
|
-
gem 'rack', '1.6.0'
|
12
|
-
|
13
|
-
gem 'mysql2', :platform => :ruby
|
14
|
-
gem 'pg', '0.21.0', :platform => :ruby
|
15
|
-
gem 'activerecord-postgis-adapter', :platform => :ruby
|
16
|
-
gem 'rgeo', :platform => :ruby
|
17
|
-
|
18
|
-
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
19
|
-
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
data/README.md
CHANGED
@@ -1,19 +1,12 @@
|
|
1
1
|
# Makara
|
2
2
|
|
3
|
-
|
3
|
+

|
4
|
+
[](https://badge.fury.io/rb/makara)
|
4
5
|
[](https://codeclimate.com/repos/526886a7f3ea00679b00cae6/feed)
|
5
6
|
|
6
7
|
|
7
8
|
Makara is generic master/slave proxy. It handles the heavy lifting of managing, choosing, blacklisting, and cycling through connections. It comes with an ActiveRecord database adapter implementation.
|
8
9
|
|
9
|
-
#### Warning:
|
10
|
-
|
11
|
-
There is a potential performance issue when used alongside certain versions of
|
12
|
-
[newrelic/rpm](https://github.com/newrelic/rpm), [Issue #59](https://github.com/taskrabbit/makara/issues/59).
|
13
|
-
|
14
|
-
> Any newrelic_rpm `< 3.11.2` and `>= 3.7.2` will have the regression.
|
15
|
-
> I'd recommend upgrading newrelic_rpm to avoid the problem.
|
16
|
-
|
17
10
|
## Installation
|
18
11
|
|
19
12
|
Use the current version of the gem from [rubygems](https://rubygems.org/gems/makara) in your `Gemfile`.
|
@@ -67,6 +60,12 @@ Makara handles stickiness by keeping track of which proxies are stuck at any giv
|
|
67
60
|
|
68
61
|
To handle persistence of context across requests in a Rack app, makara provides a middleware. It lays a cookie named `_mkra_stck` which contains the current context. If the next request is executed before the cookie expires, that given context will be used. If something occurs which naturally requires master on the second request, the context is updated and stored again.
|
69
62
|
|
63
|
+
#### Stickiness Impact
|
64
|
+
|
65
|
+
When `sticky:true`, once a query as been sent to master, all queries for the rest of the request will also be sent to master. In addition, the cookie described above will be set client side with an expiration defined by time at end of original request + `master_ttl`. As long as the cookie is valid, all requests will send queries to master.
|
66
|
+
|
67
|
+
When `sticky:false`, only queries that need to go to master will go there. Subsequent read queries in the same request will go to slaves.
|
68
|
+
|
70
69
|
#### Releasing stuck connections (clearing context)
|
71
70
|
|
72
71
|
If you need to clear the current context, releasing any stuck connections, all you have to do is:
|
data/Rakefile
CHANGED
@@ -2,24 +2,10 @@ require 'active_record/connection_adapters/makara_abstract_adapter'
|
|
2
2
|
require 'active_record/connection_adapters/jdbcmysql_adapter'
|
3
3
|
require 'active_record/connection_adapters/mysql2_makara_adapter'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def jdbcmysql_makara_connection(config)
|
10
|
-
mysql2_makara_connection(config)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
else
|
16
|
-
|
17
|
-
module ActiveRecord
|
18
|
-
class Base
|
19
|
-
def self.jdbcmysql_makara_connection(config)
|
20
|
-
self.mysql2_makara_connection(config)
|
21
|
-
end
|
5
|
+
module ActiveRecord
|
6
|
+
module ConnectionHandling
|
7
|
+
def jdbcmysql_makara_connection(config)
|
8
|
+
mysql2_makara_connection(config)
|
22
9
|
end
|
23
10
|
end
|
24
|
-
|
25
11
|
end
|
@@ -2,24 +2,10 @@ require 'active_record/connection_adapters/makara_abstract_adapter'
|
|
2
2
|
require 'active_record/connection_adapters/jdbcpostgresql_adapter'
|
3
3
|
require 'active_record/connection_adapters/postgresql_makara_adapter'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def jdbcpostgresql_makara_connection(config)
|
10
|
-
postgresql_makara_connection(config)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
else
|
16
|
-
|
17
|
-
module ActiveRecord
|
18
|
-
class Base
|
19
|
-
def self.jdbcpostgresql_makara_connection(config)
|
20
|
-
self.postgresql_makara_connection(config)
|
21
|
-
end
|
5
|
+
module ActiveRecord
|
6
|
+
module ConnectionHandling
|
7
|
+
def jdbcpostgresql_makara_connection(config)
|
8
|
+
postgresql_makara_connection(config)
|
22
9
|
end
|
23
10
|
end
|
24
|
-
|
25
11
|
end
|
@@ -4,18 +4,13 @@ require 'makara'
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
6
|
class MakaraAbstractAdapter < ::Makara::Proxy
|
7
|
-
|
8
|
-
|
9
7
|
class ErrorHandler < ::Makara::ErrorHandler
|
10
|
-
|
11
|
-
|
12
8
|
HARSH_ERRORS = [
|
13
9
|
'ActiveRecord::RecordNotUnique',
|
14
10
|
'ActiveRecord::InvalidForeignKey',
|
15
11
|
'Makara::Errors::BlacklistConnection'
|
16
12
|
].map(&:freeze).freeze
|
17
13
|
|
18
|
-
|
19
14
|
CONNECTION_MATCHERS = [
|
20
15
|
/(closed|lost|no|terminating|terminated)\s?([^\s]+)?\sconnection/,
|
21
16
|
/gone away/,
|
@@ -32,11 +27,8 @@ module ActiveRecord
|
|
32
27
|
/the database system is (starting|shutting)/
|
33
28
|
].map(&:freeze).freeze
|
34
29
|
|
35
|
-
|
36
30
|
def handle(connection)
|
37
|
-
|
38
31
|
yield
|
39
|
-
|
40
32
|
rescue Exception => e
|
41
33
|
# do it via class name to avoid version-specific constant dependencies
|
42
34
|
case e.class.name
|
@@ -49,20 +41,16 @@ module ActiveRecord
|
|
49
41
|
harshly(e)
|
50
42
|
end
|
51
43
|
end
|
52
|
-
|
53
44
|
end
|
54
45
|
|
55
|
-
|
56
46
|
def harsh_errors
|
57
47
|
HARSH_ERRORS
|
58
48
|
end
|
59
49
|
|
60
|
-
|
61
50
|
def connection_matchers
|
62
51
|
CONNECTION_MATCHERS
|
63
52
|
end
|
64
53
|
|
65
|
-
|
66
54
|
def connection_message?(message)
|
67
55
|
message = message.to_s.downcase
|
68
56
|
|
@@ -74,7 +62,6 @@ module ActiveRecord
|
|
74
62
|
end
|
75
63
|
end
|
76
64
|
|
77
|
-
|
78
65
|
def custom_error_message?(connection, message)
|
79
66
|
custom_error_matchers = connection._makara_custom_error_matchers
|
80
67
|
return false if custom_error_matchers.empty?
|
@@ -82,7 +69,6 @@ module ActiveRecord
|
|
82
69
|
message = message.to_s
|
83
70
|
|
84
71
|
custom_error_matchers.each do |matcher|
|
85
|
-
|
86
72
|
if matcher.is_a?(String)
|
87
73
|
|
88
74
|
# accept strings that look like "/.../" as a regex
|
@@ -101,49 +87,43 @@ module ActiveRecord
|
|
101
87
|
|
102
88
|
false
|
103
89
|
end
|
104
|
-
|
105
|
-
|
106
90
|
end
|
107
91
|
|
108
|
-
|
109
92
|
hijack_method :execute, :exec_query, :exec_no_cache, :exec_cache, :transaction
|
110
93
|
send_to_all :connect, :reconnect!, :verify!, :clear_cache!, :reset!
|
111
94
|
|
95
|
+
control_method :close, :steal!, :expire, :lease, :in_use?, :owner, :schema_cache, :pool=, :pool,
|
96
|
+
:schema_cache=, :lock, :seconds_idle, :==
|
97
|
+
|
112
98
|
SQL_MASTER_MATCHERS = [/\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i, /\A\s*select.+(nextval|currval|lastval|get_lock|release_lock|pg_advisory_lock|pg_advisory_unlock)\(/i].map(&:freeze).freeze
|
113
99
|
SQL_SLAVE_MATCHERS = [/\A\s*(select|with.+\)\s*select)\s/i].map(&:freeze).freeze
|
114
100
|
SQL_ALL_MATCHERS = [/\A\s*set\s/i].map(&:freeze).freeze
|
115
101
|
SQL_SKIP_STICKINESS_MATCHERS = [/\A\s*show\s([\w]+\s)?(field|table|database|schema|view|index)(es|s)?/i, /\A\s*(set|describe|explain|pragma)\s/i].map(&:freeze).freeze
|
116
102
|
|
117
|
-
|
118
103
|
def sql_master_matchers
|
119
104
|
SQL_MASTER_MATCHERS
|
120
105
|
end
|
121
106
|
|
122
|
-
|
123
107
|
def sql_slave_matchers
|
124
108
|
SQL_SLAVE_MATCHERS
|
125
109
|
end
|
126
110
|
|
127
|
-
|
128
111
|
def sql_all_matchers
|
129
112
|
SQL_ALL_MATCHERS
|
130
113
|
end
|
131
114
|
|
132
|
-
|
133
115
|
def sql_skip_stickiness_matchers
|
134
116
|
SQL_SKIP_STICKINESS_MATCHERS
|
135
117
|
end
|
136
118
|
|
137
|
-
|
138
119
|
def initialize(config)
|
139
120
|
@error_handler = ::ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler.new
|
121
|
+
@control = ActiveRecordPoolControl.new(self)
|
140
122
|
super(config)
|
141
123
|
end
|
142
124
|
|
143
|
-
|
144
125
|
protected
|
145
126
|
|
146
|
-
|
147
127
|
def appropriate_connection(method_name, args, &block)
|
148
128
|
if needed_by_all?(method_name, args)
|
149
129
|
|
@@ -164,29 +144,28 @@ module ActiveRecord
|
|
164
144
|
end
|
165
145
|
end
|
166
146
|
|
167
|
-
|
168
147
|
def should_stick?(method_name, args)
|
169
148
|
sql = coerce_query_to_sql_string(args.first)
|
170
149
|
return false if sql_skip_stickiness_matchers.any?{|m| sql =~ m }
|
150
|
+
|
171
151
|
super
|
172
152
|
end
|
173
153
|
|
174
|
-
|
175
154
|
def needed_by_all?(method_name, args)
|
176
155
|
sql = coerce_query_to_sql_string(args.first)
|
177
156
|
return true if sql_all_matchers.any?{|m| sql =~ m }
|
157
|
+
|
178
158
|
false
|
179
159
|
end
|
180
160
|
|
181
|
-
|
182
161
|
def needs_master?(method_name, args)
|
183
162
|
sql = coerce_query_to_sql_string(args.first)
|
184
163
|
return true if sql_master_matchers.any?{|m| sql =~ m }
|
185
164
|
return false if sql_slave_matchers.any?{|m| sql =~ m }
|
165
|
+
|
186
166
|
true
|
187
167
|
end
|
188
168
|
|
189
|
-
|
190
169
|
def coerce_query_to_sql_string(sql_or_arel)
|
191
170
|
if sql_or_arel.respond_to?(:to_sql)
|
192
171
|
sql_or_arel.to_sql
|
@@ -195,18 +174,116 @@ module ActiveRecord
|
|
195
174
|
end
|
196
175
|
end
|
197
176
|
|
198
|
-
|
199
177
|
def connection_for(config)
|
200
178
|
config = Makara::ConfigParser.merge_and_resolve_default_url_config(config)
|
201
179
|
active_record_connection_for(config)
|
202
180
|
end
|
203
181
|
|
204
|
-
|
205
182
|
def active_record_connection_for(config)
|
206
183
|
raise NotImplementedError
|
207
184
|
end
|
208
185
|
|
186
|
+
class ActiveRecordPoolControl
|
187
|
+
attr_reader :owner
|
188
|
+
alias :in_use? :owner
|
189
|
+
|
190
|
+
def initialize(proxy)
|
191
|
+
@proxy = proxy
|
192
|
+
@owner = nil
|
193
|
+
@pool = nil
|
194
|
+
@schema_cache = ActiveRecord::ConnectionAdapters::SchemaCache.new @proxy
|
195
|
+
@idle_since = Concurrent.monotonic_time
|
196
|
+
@adapter = ActiveRecord::ConnectionAdapters::AbstractAdapter.new(@proxy)
|
197
|
+
end
|
198
|
+
|
199
|
+
def close(*args)
|
200
|
+
@pool.checkin @proxy
|
201
|
+
end
|
202
|
+
|
203
|
+
# this method must only be called while holding connection pool's mutex
|
204
|
+
def lease(*args)
|
205
|
+
if in_use?
|
206
|
+
msg = +"Cannot lease connection, "
|
207
|
+
if @owner == Thread.current
|
208
|
+
msg << "it is already leased by the current thread."
|
209
|
+
else
|
210
|
+
msg << "it is already in use by a different thread: #{@owner}. " \
|
211
|
+
"Current thread: #{Thread.current}."
|
212
|
+
end
|
213
|
+
raise ActiveRecordError, msg
|
214
|
+
end
|
215
|
+
@owner = Thread.current
|
216
|
+
end
|
217
|
+
|
218
|
+
# this method must only be called while holding connection pool's mutex
|
219
|
+
def expire(*args)
|
220
|
+
if in_use?
|
221
|
+
if @owner != Thread.current
|
222
|
+
raise ActiveRecordError, "Cannot expire connection, " \
|
223
|
+
"it is owned by a different thread: #{@owner}. " \
|
224
|
+
"Current thread: #{Thread.current}."
|
225
|
+
end
|
226
|
+
|
227
|
+
@idle_since = Concurrent.monotonic_time
|
228
|
+
@owner = nil
|
229
|
+
else
|
230
|
+
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# Seconds since this connection was returned to the pool
|
235
|
+
def seconds_idle(*args)
|
236
|
+
return 0 if in_use?
|
237
|
+
|
238
|
+
Concurrent.monotonic_time - @idle_since
|
239
|
+
end
|
240
|
+
|
241
|
+
# this method must only be called while holding connection pool's mutex (and a desire for segfaults)
|
242
|
+
def steal!(*args)
|
243
|
+
if in_use?
|
244
|
+
if @owner != Thread.current
|
245
|
+
@pool.send :remove_connection_from_thread_cache, @proxy, @owner
|
246
|
+
@owner = Thread.current
|
247
|
+
end
|
248
|
+
else
|
249
|
+
raise ActiveRecordError, "Cannot steal connection, it is not currently leased."
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def schema_cache(*args)
|
254
|
+
if @pool.respond_to?(:get_schema_cache) # AR6
|
255
|
+
@pool.get_schema_cache(@proxy)
|
256
|
+
else
|
257
|
+
@schema_cache
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def schema_cache=(*args)
|
262
|
+
cache = args[0]
|
263
|
+
cache.connection = @proxy
|
264
|
+
if @pool.respond_to?(:set_schema_cache) # AR6
|
265
|
+
@pool.set_schema_cache(cache)
|
266
|
+
else
|
267
|
+
@schema_cache = cache
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def lock(*args)
|
272
|
+
@adapter.lock
|
273
|
+
end
|
274
|
+
|
275
|
+
def pool=(*args)
|
276
|
+
@pool = args[0]
|
277
|
+
end
|
209
278
|
|
279
|
+
def pool(*args)
|
280
|
+
@pool
|
281
|
+
end
|
282
|
+
|
283
|
+
def ==(*args)
|
284
|
+
@proxy.object_id == args[0].object_id
|
285
|
+
end
|
286
|
+
end
|
210
287
|
end
|
211
288
|
end
|
212
289
|
end
|