makara 0.3.9 → 0.3.10
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/.travis.yml +35 -0
- data/CHANGELOG.md +23 -1
- data/Gemfile +1 -1
- data/README.md +9 -2
- data/gemfiles/ar-head.gemfile +10 -1
- data/gemfiles/ar30.gemfile +7 -3
- data/gemfiles/ar31.gemfile +8 -3
- data/gemfiles/ar32.gemfile +8 -3
- data/gemfiles/ar40.gemfile +10 -3
- data/gemfiles/ar41.gemfile +10 -3
- data/gemfiles/ar42.gemfile +10 -3
- data/gemfiles/ar50.gemfile +10 -1
- data/gemfiles/ar51.gemfile +10 -1
- data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +3 -3
- data/lib/makara/cache/memory_store.rb +4 -1
- data/lib/makara/connection_wrapper.rb +2 -2
- data/lib/makara/pool.rb +4 -7
- data/lib/makara/proxy.rb +0 -1
- data/lib/makara/strategies/round_robin.rb +6 -0
- data/lib/makara/version.rb +1 -1
- data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +10 -1
- data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +16 -1
- data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +10 -5
- data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +17 -1
- data/spec/cache_spec.rb +22 -0
- data/spec/connection_wrapper_spec.rb +5 -2
- data/spec/spec_helper.rb +2 -0
- data/spec/support/mysql2_database.yml +1 -0
- data/spec/support/mysql2_database_with_custom_errors.yml +5 -0
- data/spec/support/postgis_database.yml +2 -0
- data/spec/support/postgis_schema.rb +6 -3
- data/spec/support/postgresql_database.yml +2 -0
- data/spec/support/schema.rb +5 -5
- data/spec/support/user.rb +5 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4dc4867024ed5527a9b0a499e4daff0c9c4bac5e
|
|
4
|
+
data.tar.gz: 170743d2e7f735b39fbcb477657643918c66cd32
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8da212514ba19441a154323990544bb18ce0a3a39ff133f227bab84790e48b747f254b53d9a59c2aa93cfad0f0367fd03a44d3bcbe94a17874e7f2b084bec468
|
|
7
|
+
data.tar.gz: 731c52cd786a65d0a124edf94e1f721b69ec78cee0549d499b2cc35a5ac2210aa7ae87d8b22a3734829271ea538ed6b3cfb197fd1ebc2d4ce0f961d16e86afda
|
data/.travis.yml
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
sudo: false
|
|
2
2
|
language: ruby
|
|
3
3
|
cache: bundler
|
|
4
|
+
dist: precise
|
|
4
5
|
|
|
5
6
|
services:
|
|
6
7
|
- mysql
|
|
7
8
|
- postgresql
|
|
8
9
|
|
|
10
|
+
before_install:
|
|
11
|
+
- gem install bundler
|
|
12
|
+
|
|
9
13
|
before_script:
|
|
10
14
|
- mysql -e 'create database makara_test;'
|
|
11
15
|
- psql -c 'create database makara_test;' -U postgres
|
|
@@ -17,6 +21,7 @@ rvm:
|
|
|
17
21
|
- 2.2
|
|
18
22
|
- 2.3
|
|
19
23
|
- 2.4
|
|
24
|
+
- 2.5.0
|
|
20
25
|
- ruby-head
|
|
21
26
|
- jruby
|
|
22
27
|
|
|
@@ -43,8 +48,34 @@ matrix:
|
|
|
43
48
|
rvm: 2.3
|
|
44
49
|
- gemfile: gemfiles/ar30.gemfile
|
|
45
50
|
rvm: 2.4
|
|
51
|
+
- gemfile: gemfiles/ar31.gemfile
|
|
52
|
+
rvm: 2.4
|
|
53
|
+
- gemfile: gemfiles/ar32.gemfile
|
|
54
|
+
rvm: 2.4
|
|
55
|
+
- gemfile: gemfiles/ar40.gemfile
|
|
56
|
+
rvm: 2.4
|
|
57
|
+
- gemfile: gemfiles/ar41.gemfile
|
|
58
|
+
rvm: 2.4
|
|
59
|
+
- gemfile: gemfiles/ar30.gemfile
|
|
60
|
+
rvm: 2.5.0
|
|
61
|
+
- gemfile: gemfiles/ar31.gemfile
|
|
62
|
+
rvm: 2.5.0
|
|
63
|
+
- gemfile: gemfiles/ar32.gemfile
|
|
64
|
+
rvm: 2.5.0
|
|
65
|
+
- gemfile: gemfiles/ar40.gemfile
|
|
66
|
+
rvm: 2.5.0
|
|
67
|
+
- gemfile: gemfiles/ar41.gemfile
|
|
68
|
+
rvm: 2.5.0
|
|
46
69
|
- gemfile: gemfiles/ar30.gemfile
|
|
47
70
|
rvm: ruby-head
|
|
71
|
+
- gemfile: gemfiles/ar31.gemfile
|
|
72
|
+
rvm: ruby-head
|
|
73
|
+
- gemfile: gemfiles/ar32.gemfile
|
|
74
|
+
rvm: ruby-head
|
|
75
|
+
- gemfile: gemfiles/ar40.gemfile
|
|
76
|
+
rvm: ruby-head
|
|
77
|
+
- gemfile: gemfiles/ar41.gemfile
|
|
78
|
+
rvm: ruby-head
|
|
48
79
|
- gemfile: gemfiles/ar50.gemfile
|
|
49
80
|
rvm: 2.0
|
|
50
81
|
- gemfile: gemfiles/ar50.gemfile
|
|
@@ -63,6 +94,10 @@ matrix:
|
|
|
63
94
|
rvm: 2.1
|
|
64
95
|
- gemfile: gemfiles/ar-head.gemfile
|
|
65
96
|
rvm: 2.2
|
|
97
|
+
- gemfile: gemfiles/ar-head.gemfile
|
|
98
|
+
rvm: 2.3
|
|
99
|
+
- gemfile: gemfiles/ar-head.gemfile
|
|
100
|
+
rvm: 2.4
|
|
66
101
|
allow_failures:
|
|
67
102
|
- gemfile: gemfiles/ar-head.gemfile
|
|
68
103
|
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
-
## v0.3.
|
|
4
|
+
## v0.3.9 - 2013-03-20
|
|
5
|
+
[Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.9...v0.3.10)
|
|
6
|
+
|
|
7
|
+
Fixed
|
|
8
|
+
- Send nextval queries to master and show queries to replicas for Postgres [#173](https://github.com/taskrabbit/makara/pull/173) Andrew Kane
|
|
9
|
+
- Fixes can't add a new key into hash during iteration error [#174](https://github.com/taskrabbit/makara/pull/174) Andrew Kane
|
|
10
|
+
- Fix: an application freezes when a slave is down [#180](https://github.com/taskrabbit/makara/pull/180) Alexey P
|
|
11
|
+
- Allow SELECTs that use common table expressions to go to replicas [#184](https://github.com/taskrabbit/makara/pull/184) Andrew Kane
|
|
12
|
+
- Send advisory lock requests to the master [#198](https://github.com/taskrabbit/makara/pull/198) George Claghorn
|
|
13
|
+
- Postgres exists query [#199](https://github.com/taskrabbit/makara/pull/199) Brian Leonard
|
|
14
|
+
|
|
15
|
+
Documentation and Test
|
|
16
|
+
- Clarify README's "What goes where" [#187](https://github.com/taskrabbit/makara/pull/187) Jan Sandbrink
|
|
17
|
+
- Fix loading fixtures in Rails 5.2 [#192](https://github.com/taskrabbit/makara/pull/192) George Claghorn
|
|
18
|
+
- Travis Upgrade [#199](https://github.com/taskrabbit/makara/pull/199) Brian Leonard
|
|
19
|
+
|
|
20
|
+
## v0.3.9 - 2017-08-14
|
|
21
|
+
[Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.8...v0.3.9)
|
|
22
|
+
|
|
23
|
+
Changed
|
|
24
|
+
- Add postgis support [#118](https://github.com/taskrabbit/makara/pull/118) Kevin Bacha
|
|
25
|
+
|
|
26
|
+
## v0.3.8 - 2017-07-11
|
|
5
27
|
|
|
6
28
|
[Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.7...v0.3.8)
|
|
7
29
|
|
data/Gemfile
CHANGED
|
@@ -11,7 +11,7 @@ gem 'ruby-debug', :platform => :jruby
|
|
|
11
11
|
gem 'rack', '1.6.0'
|
|
12
12
|
|
|
13
13
|
gem 'mysql2', :platform => :ruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
16
16
|
gem 'rgeo', :platform => :ruby
|
|
17
17
|
|
data/README.md
CHANGED
|
@@ -120,7 +120,13 @@ By creating a makara database adapter which simply acts as a proxy we avoid any
|
|
|
120
120
|
|
|
121
121
|
### What goes where?
|
|
122
122
|
|
|
123
|
-
Any `SELECT` statements will execute against your slave(s), anything else will go to master.
|
|
123
|
+
In general: Any `SELECT` statements will execute against your slave(s), anything else will go to master.
|
|
124
|
+
|
|
125
|
+
There are some edge cases:
|
|
126
|
+
* `SET` operations will be sent to all connections
|
|
127
|
+
* Execution of specific methods such as `connect!`, `disconnect!`, and `clear_cache!` are invoked on all underlying connections
|
|
128
|
+
* Calls inside a transaction will always be sent to the master (otherwise changes from within the transaction could not be read back on most transaction isolation levels)
|
|
129
|
+
* Locking reads (e.g. `SELECT ... FOR UPDATE`) will always be sent to the master
|
|
124
130
|
|
|
125
131
|
### Errors / blacklisting
|
|
126
132
|
|
|
@@ -165,7 +171,8 @@ The makara subconfig sets up the proxy with a few of its own options, then provi
|
|
|
165
171
|
* disable_blacklist - do not blacklist node at any error, useful in case of one master
|
|
166
172
|
* sticky - if a node should be stuck to once it's used during a specific context
|
|
167
173
|
* master_ttl - how long the master context is persisted. generally, this needs to be longer than any replication lag
|
|
168
|
-
* master_strategy - use a different strategy for picking the "current" node: `failover` will try to keep the same one until it is blacklisted. The default is `round_robin` which will cycle through available ones.
|
|
174
|
+
* master_strategy - use a different strategy for picking the "current" master node: `failover` will try to keep the same one until it is blacklisted. The default is `round_robin` which will cycle through available ones.
|
|
175
|
+
* slave_strategy - use a different strategy for picking the "current" slave node: `failover` will try to keep the same one until it is blacklisted. The default is `round_robin` which will cycle through available ones.
|
|
169
176
|
* connection_error_matchers - array of custom error matchers you want to be handled gracefully by Makara (as in, errors matching these regexes will result in blacklisting the connection as opposed to raising directly).
|
|
170
177
|
|
|
171
178
|
Connection definitions contain any extra node-specific configurations. If the node should behave as a master you must provide `role: master`. Any previous configurations can be overridden within a specific node's config. Nodes can also contain weights if you'd like to balance usage based on hardware specifications. Optionally, you can provide a name attribute which will be used in sql logging.
|
data/gemfiles/ar-head.gemfile
CHANGED
|
@@ -11,5 +11,14 @@ gem 'rack'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
data/gemfiles/ar30.gemfile
CHANGED
|
@@ -12,8 +12,6 @@ gem 'i18n', '~> 0.5.0'
|
|
|
12
12
|
gem 'mysql2', '0.2.11', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
14
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
15
|
-
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
16
|
-
gem 'rgeo', :platform => :ruby
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
@@ -28,5 +26,11 @@ end
|
|
|
28
26
|
if rmajor == 1 && (rminor == 8 || (rminor == 9 && rpatch < 3))
|
|
29
27
|
gem 'pg', '0.17.1', :platform => :ruby
|
|
30
28
|
else
|
|
31
|
-
gem 'pg', :platform => :ruby
|
|
29
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# 2.1 +
|
|
33
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
34
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
35
|
+
gem 'rgeo', :platform => :ruby
|
|
32
36
|
end
|
data/gemfiles/ar31.gemfile
CHANGED
|
@@ -12,8 +12,7 @@ gem 'i18n', '~> 0.6.0'
|
|
|
12
12
|
gem 'mysql2', '~> 0.3.10', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
14
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
15
|
-
|
|
16
|
-
gem 'rgeo', :platform => :ruby
|
|
15
|
+
|
|
17
16
|
|
|
18
17
|
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
18
|
|
|
@@ -27,5 +26,11 @@ end
|
|
|
27
26
|
if rmajor == 1 && (rminor == 8 || (rminor == 9 && rpatch < 3))
|
|
28
27
|
gem 'pg', '0.17.1', :platform => :ruby
|
|
29
28
|
else
|
|
30
|
-
gem 'pg', :platform => :ruby
|
|
29
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# 2.1 +
|
|
33
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
34
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
35
|
+
gem 'rgeo', :platform => :ruby
|
|
31
36
|
end
|
data/gemfiles/ar32.gemfile
CHANGED
|
@@ -12,8 +12,7 @@ gem 'i18n', '~> 0.6.0'
|
|
|
12
12
|
gem 'mysql2', '~> 0.3.10', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
14
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
15
|
-
|
|
16
|
-
gem 'rgeo', :platform => :ruby
|
|
15
|
+
|
|
17
16
|
|
|
18
17
|
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
18
|
|
|
@@ -27,5 +26,11 @@ end
|
|
|
27
26
|
if rmajor == 1 && (rminor == 8 || (rminor == 9 && rpatch < 3))
|
|
28
27
|
gem 'pg', '0.17.1', :platform => :ruby
|
|
29
28
|
else
|
|
30
|
-
gem 'pg', :platform => :ruby
|
|
29
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# 2.1 +
|
|
33
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
34
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
35
|
+
gem 'rgeo', :platform => :ruby
|
|
31
36
|
end
|
data/gemfiles/ar40.gemfile
CHANGED
|
@@ -11,7 +11,14 @@ gem 'rack', '1.6.0'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', '~> 0.3.10', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
data/gemfiles/ar41.gemfile
CHANGED
|
@@ -11,7 +11,14 @@ gem 'rack', '1.6.0'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', '~> 0.3.10', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
data/gemfiles/ar42.gemfile
CHANGED
|
@@ -11,7 +11,14 @@ gem 'rack', '1.6.0'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', '~> 0.3.10', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
data/gemfiles/ar50.gemfile
CHANGED
|
@@ -11,5 +11,14 @@ gem 'rack'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
data/gemfiles/ar51.gemfile
CHANGED
|
@@ -11,5 +11,14 @@ gem 'rack'
|
|
|
11
11
|
gem 'timecop'
|
|
12
12
|
gem 'mysql2', :platform => :ruby
|
|
13
13
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
|
14
|
-
gem 'pg', :platform => :ruby
|
|
14
|
+
gem 'pg', '0.21.0', :platform => :ruby
|
|
15
15
|
gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
19
|
+
|
|
20
|
+
# 2.1 +
|
|
21
|
+
if rmajor > 2 || (rmajor == 2 && rminor >= 1)
|
|
22
|
+
gem 'activerecord-postgis-adapter', :platform => :ruby
|
|
23
|
+
gem 'rgeo', :platform => :ruby
|
|
24
|
+
end
|
|
@@ -105,11 +105,11 @@ module ActiveRecord
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
hijack_method :execute, :
|
|
108
|
+
hijack_method :execute, :exec_query, :exec_no_cache, :exec_cache, :transaction
|
|
109
109
|
send_to_all :connect, :reconnect!, :verify!, :clear_cache!, :reset!
|
|
110
110
|
|
|
111
|
-
SQL_MASTER_MATCHERS = [/\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i].map(&:freeze).freeze
|
|
112
|
-
SQL_SLAVE_MATCHERS = [/\A\s*select\s/i].map(&:freeze).freeze
|
|
111
|
+
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
|
|
112
|
+
SQL_SLAVE_MATCHERS = [/\A\s*(select|with.+\)\s*select)\s/i].map(&:freeze).freeze
|
|
113
113
|
SQL_ALL_MATCHERS = [/\A\s*set\s/i].map(&:freeze).freeze
|
|
114
114
|
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
|
|
115
115
|
|
|
@@ -4,6 +4,7 @@ module Makara
|
|
|
4
4
|
|
|
5
5
|
def initialize
|
|
6
6
|
@data = {}
|
|
7
|
+
@mutex = Mutex.new
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def read(key)
|
|
@@ -20,7 +21,9 @@ module Makara
|
|
|
20
21
|
protected
|
|
21
22
|
|
|
22
23
|
def clean
|
|
23
|
-
@
|
|
24
|
+
@mutex.synchronize do
|
|
25
|
+
@data.delete_if{|k,v| v[1] <= Time.now.to_i }
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
end
|
|
@@ -146,10 +146,10 @@ module Makara
|
|
|
146
146
|
# The new definition should allow for the proxy to intercept the invocation if required.
|
|
147
147
|
@proxy.class.hijack_methods.each do |meth|
|
|
148
148
|
extension << %Q{
|
|
149
|
-
def #{meth}(*args)
|
|
149
|
+
def #{meth}(*args, &block)
|
|
150
150
|
_makara_hijack do |proxy|
|
|
151
151
|
if proxy
|
|
152
|
-
proxy.#{meth}(*args)
|
|
152
|
+
proxy.#{meth}(*args, &block)
|
|
153
153
|
else
|
|
154
154
|
super
|
|
155
155
|
end
|
data/lib/makara/pool.rb
CHANGED
|
@@ -64,17 +64,14 @@ module Makara
|
|
|
64
64
|
@connections.each do |con|
|
|
65
65
|
next if con._makara_blacklisted?
|
|
66
66
|
begin
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
ret = @proxy.error_handler.handle(con) do
|
|
68
|
+
if block
|
|
69
69
|
yield con
|
|
70
|
+
else
|
|
71
|
+
con.send(method, *args)
|
|
70
72
|
end
|
|
71
73
|
end
|
|
72
74
|
|
|
73
|
-
if method
|
|
74
|
-
ret = con.send(method, *args)
|
|
75
|
-
else
|
|
76
|
-
ret = value
|
|
77
|
-
end
|
|
78
75
|
one_worked = true
|
|
79
76
|
rescue Makara::Errors::BlacklistConnection => e
|
|
80
77
|
errors.insert(0, e)
|
data/lib/makara/proxy.rb
CHANGED
|
@@ -23,6 +23,8 @@ module Makara
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def next
|
|
26
|
+
return safe_value(0, true) if single_one?
|
|
27
|
+
|
|
26
28
|
idx = @current_idx
|
|
27
29
|
begin
|
|
28
30
|
|
|
@@ -67,6 +69,10 @@ module Makara
|
|
|
67
69
|
def should_shuffle?
|
|
68
70
|
true
|
|
69
71
|
end
|
|
72
|
+
|
|
73
|
+
def single_one?
|
|
74
|
+
false
|
|
75
|
+
end
|
|
70
76
|
end
|
|
71
77
|
end
|
|
72
78
|
end
|
data/lib/makara/version.rb
CHANGED
|
@@ -27,7 +27,16 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
|
|
|
27
27
|
' select * from users for update' => true,
|
|
28
28
|
'select * from users lock in share mode' => true,
|
|
29
29
|
'select * from users where name = "for update"' => false,
|
|
30
|
-
'select * from users where name = "lock in share mode"' => false
|
|
30
|
+
'select * from users where name = "lock in share mode"' => false,
|
|
31
|
+
'select nextval(\'users_id_seq\')' => true,
|
|
32
|
+
'select currval(\'users_id_seq\')' => true,
|
|
33
|
+
'select lastval()' => true,
|
|
34
|
+
'with fence as (select * from users) select * from fence' => false,
|
|
35
|
+
'with fence as (select * from felines) insert to cats' => true,
|
|
36
|
+
'select get_lock(\'foo\', 0)' => true,
|
|
37
|
+
'select release_lock(\'foo\')' => true,
|
|
38
|
+
'select pg_advisory_lock(12345)' => true,
|
|
39
|
+
'select pg_advisory_unlock(12345)' => true
|
|
31
40
|
}.each do |sql, should_go_to_master|
|
|
32
41
|
|
|
33
42
|
it "determines that \"#{sql}\" #{should_go_to_master ? 'requires' : 'does not require'} master" do
|
|
@@ -150,7 +150,7 @@ describe 'MakaraMysql2Adapter' do
|
|
|
150
150
|
|
|
151
151
|
it 'should send reads to the slave' do
|
|
152
152
|
# ensure the next connection will be the first one
|
|
153
|
-
|
|
153
|
+
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
|
154
154
|
|
|
155
155
|
con = connection.slave_pool.connections.first
|
|
156
156
|
expect(con).to receive(:execute).with('SELECT * FROM users').once
|
|
@@ -158,6 +158,21 @@ describe 'MakaraMysql2Adapter' do
|
|
|
158
158
|
connection.execute('SELECT * FROM users')
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
+
it 'should send exists? to slave' do
|
|
162
|
+
next if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 # query doesn't work?
|
|
163
|
+
|
|
164
|
+
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
|
165
|
+
Test::User.exists? # flush other (schema) things that need to happen
|
|
166
|
+
|
|
167
|
+
con = connection.slave_pool.connections.first
|
|
168
|
+
if (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR <= 0)
|
|
169
|
+
expect(con).to receive(:execute).with(/SELECT\s+1\s*(AS one)?\s+FROM .?users.?\s+LIMIT\s+.?1/, any_args).once.and_call_original
|
|
170
|
+
else
|
|
171
|
+
expect(con).to receive(:exec_query).with(/SELECT\s+1\s*(AS one)?\s+FROM .?users.?\s+LIMIT\s+.?1/, any_args).once.and_call_original
|
|
172
|
+
end
|
|
173
|
+
Test::User.exists?
|
|
174
|
+
end
|
|
175
|
+
|
|
161
176
|
it 'should send writes to master' do
|
|
162
177
|
con = connection.master_pool.connections.first
|
|
163
178
|
expect(con).to receive(:execute).with('UPDATE users SET name = "bob" WHERE id = 1')
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# RGeo doesn't play well with JRuby and to avoid complicated test setup
|
|
2
2
|
# we're only testing ActiveRecord version ~> 4.2
|
|
3
|
+
# also rgeo only works on 2.1+
|
|
4
|
+
|
|
5
|
+
rmajor, rminor, rpatch = RUBY_VERSION.split(/[^\d]/)[0..2].map(&:to_i)
|
|
6
|
+
require 'active_record'
|
|
7
|
+
|
|
8
|
+
# TODO: test this in AR 5+ ?
|
|
9
|
+
|
|
3
10
|
if RUBY_ENGINE == 'ruby' &&
|
|
4
11
|
ActiveRecord::VERSION::MAJOR == 4 &&
|
|
5
|
-
ActiveRecord::VERSION::MINOR >= 2
|
|
12
|
+
ActiveRecord::VERSION::MINOR >= 2 &&
|
|
13
|
+
(rmajor > 2 || (rmajor == 2 && rminor >= 1))
|
|
6
14
|
|
|
7
15
|
require 'spec_helper'
|
|
8
16
|
require 'rgeo'
|
|
@@ -83,10 +91,7 @@ if RUBY_ENGINE == 'ruby' &&
|
|
|
83
91
|
|
|
84
92
|
it 'should send reads to the slave' do
|
|
85
93
|
# ensure the next connection will be the first one
|
|
86
|
-
|
|
87
|
-
.strategy
|
|
88
|
-
.instance_variable_set('@current_idx',
|
|
89
|
-
connection.slave_pool.connections.length)
|
|
94
|
+
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
|
90
95
|
|
|
91
96
|
con = connection.slave_pool.connections.first
|
|
92
97
|
expect(con).to receive(:execute).with('SELECT * FROM users').once
|
|
@@ -64,7 +64,7 @@ describe 'MakaraPostgreSQLAdapter' do
|
|
|
64
64
|
|
|
65
65
|
it 'should send reads to the slave' do
|
|
66
66
|
# ensure the next connection will be the first one
|
|
67
|
-
|
|
67
|
+
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
|
68
68
|
|
|
69
69
|
con = connection.slave_pool.connections.first
|
|
70
70
|
expect(con).to receive(:execute).with('SELECT * FROM users').once
|
|
@@ -72,6 +72,22 @@ describe 'MakaraPostgreSQLAdapter' do
|
|
|
72
72
|
connection.execute('SELECT * FROM users')
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
it 'should send exists? to slave' do
|
|
76
|
+
next if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 # query doesn't work?
|
|
77
|
+
|
|
78
|
+
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
|
79
|
+
Test::User.exists? # flush other (schema) things that need to happen
|
|
80
|
+
|
|
81
|
+
con = connection.slave_pool.connections.first
|
|
82
|
+
if (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2) ||
|
|
83
|
+
(ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR <= 0)
|
|
84
|
+
expect(con).to receive(:exec_no_cache).with(/SELECT\s+1\s*(AS one)?\s+FROM .?users.?\s+LIMIT\s+.?1/, any_args).once.and_call_original
|
|
85
|
+
else
|
|
86
|
+
expect(con).to receive(:exec_query).with(/SELECT\s+1\s*(AS one)?\s+FROM .?users.?\s+LIMIT\s+.?1/, any_args).once.and_call_original
|
|
87
|
+
end
|
|
88
|
+
Test::User.exists?
|
|
89
|
+
end
|
|
90
|
+
|
|
75
91
|
it 'should send writes to master' do
|
|
76
92
|
con = connection.master_pool.connections.first
|
|
77
93
|
expect(con).to receive(:execute).with('UPDATE users SET name = "bob" WHERE id = 1')
|
data/spec/cache_spec.rb
CHANGED
|
@@ -52,6 +52,28 @@ describe Makara::Cache do
|
|
|
52
52
|
expect(data).not_to have_key('test')
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
it 'has thread-safety' do
|
|
56
|
+
store = Makara::Cache::MemoryStore.new
|
|
57
|
+
previous_value = Thread.abort_on_exception
|
|
58
|
+
|
|
59
|
+
begin
|
|
60
|
+
Thread.abort_on_exception = true
|
|
61
|
+
|
|
62
|
+
workers = 2.times.map do
|
|
63
|
+
Thread.new do
|
|
64
|
+
100.times do |n|
|
|
65
|
+
store.write(n, 'value', expires_in: 0.5)
|
|
66
|
+
sleep(0.01)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
expect { workers.map(&:join) }.to_not raise_error
|
|
72
|
+
ensure
|
|
73
|
+
Thread.abort_on_exception = previous_value
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
55
77
|
end
|
|
56
78
|
|
|
57
79
|
|
|
@@ -14,8 +14,11 @@ describe Makara::ConnectionWrapper do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it 'should invoke hijacked methods on the proxy when invoked directly' do
|
|
17
|
-
expect(proxy).to receive(:execute).with('test').once
|
|
18
|
-
|
|
17
|
+
expect(proxy).to receive(:execute).with('test').once do |&block|
|
|
18
|
+
expect(block.call).to eq('Hello')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
connection.execute('test') { 'Hello' }
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
it 'should have a default weight of 1' do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -24,6 +24,7 @@ RSpec.configure do |config|
|
|
|
24
24
|
require "#{File.dirname(__FILE__)}/support/pool_extensions"
|
|
25
25
|
require "#{File.dirname(__FILE__)}/support/mock_objects"
|
|
26
26
|
require "#{File.dirname(__FILE__)}/support/deep_dup"
|
|
27
|
+
require "#{File.dirname(__FILE__)}/support/user"
|
|
27
28
|
|
|
28
29
|
config.include SpecHelpers
|
|
29
30
|
|
|
@@ -31,6 +32,7 @@ RSpec.configure do |config|
|
|
|
31
32
|
Makara::Cache.store = :memory
|
|
32
33
|
change_context
|
|
33
34
|
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:should_shuffle?){ false }
|
|
35
|
+
RSpec::Mocks.space.proxy_for(ActiveRecord::Base).reset # make sure not stubbed in some way
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def change_context
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
conn = ActiveRecord::Base.connection
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
execute "create extension if not exists postgis"
|
|
3
|
+
conn.execute "create extension if not exists postgis"
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
if conn.table_exists? "towns"
|
|
6
|
+
conn.execute("TRUNCATE TABLE towns")
|
|
7
|
+
else
|
|
8
|
+
conn.create_table "towns", :force => true do |t|
|
|
6
9
|
t.st_point "location"
|
|
7
10
|
end
|
|
8
11
|
end
|
data/spec/support/schema.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
ActiveRecord::
|
|
1
|
+
conn = ActiveRecord::Base.connection
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
if conn.table_exists? "users"
|
|
4
|
+
conn.execute("TRUNCATE TABLE users")
|
|
5
|
+
else
|
|
6
|
+
conn.create_table "users" do |t|
|
|
6
7
|
t.string "name"
|
|
7
8
|
end
|
|
8
|
-
|
|
9
9
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: makara
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Nelson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-03-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -108,6 +108,7 @@ files:
|
|
|
108
108
|
- spec/support/postgresql_database.yml
|
|
109
109
|
- spec/support/proxy_extensions.rb
|
|
110
110
|
- spec/support/schema.rb
|
|
111
|
+
- spec/support/user.rb
|
|
111
112
|
homepage: ''
|
|
112
113
|
licenses: []
|
|
113
114
|
metadata: {}
|
|
@@ -158,3 +159,4 @@ test_files:
|
|
|
158
159
|
- spec/support/postgresql_database.yml
|
|
159
160
|
- spec/support/proxy_extensions.rb
|
|
160
161
|
- spec/support/schema.rb
|
|
162
|
+
- spec/support/user.rb
|