makara 0.3.8 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-publish-public.yml +36 -0
  3. data/.travis.yml +71 -9
  4. data/CHANGELOG.md +84 -25
  5. data/Gemfile +4 -3
  6. data/README.md +37 -34
  7. data/gemfiles/ar-head.gemfile +9 -0
  8. data/gemfiles/ar30.gemfile +7 -1
  9. data/gemfiles/ar31.gemfile +8 -1
  10. data/gemfiles/ar32.gemfile +8 -1
  11. data/gemfiles/ar40.gemfile +10 -1
  12. data/gemfiles/ar41.gemfile +10 -1
  13. data/gemfiles/ar42.gemfile +10 -1
  14. data/gemfiles/ar50.gemfile +11 -2
  15. data/gemfiles/ar51.gemfile +11 -2
  16. data/gemfiles/ar52.gemfile +24 -0
  17. data/gemfiles/ar60.gemfile +24 -0
  18. data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +109 -3
  19. data/lib/active_record/connection_adapters/makara_postgis_adapter.rb +41 -0
  20. data/lib/makara.rb +15 -4
  21. data/lib/makara/cache.rb +4 -40
  22. data/lib/makara/config_parser.rb +14 -3
  23. data/lib/makara/connection_wrapper.rb +26 -2
  24. data/lib/makara/context.rb +108 -38
  25. data/lib/makara/cookie.rb +52 -0
  26. data/lib/makara/error_handler.rb +2 -2
  27. data/lib/makara/errors/blacklisted_while_in_transaction.rb +14 -0
  28. data/lib/makara/errors/invalid_shard.rb +16 -0
  29. data/lib/makara/logging/logger.rb +1 -1
  30. data/lib/makara/middleware.rb +12 -75
  31. data/lib/makara/pool.rb +53 -40
  32. data/lib/makara/proxy.rb +52 -30
  33. data/lib/makara/railtie.rb +0 -6
  34. data/lib/makara/strategies/round_robin.rb +6 -0
  35. data/lib/makara/strategies/shard_aware.rb +47 -0
  36. data/lib/makara/version.rb +2 -2
  37. data/makara.gemspec +5 -1
  38. data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +10 -5
  39. data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +17 -2
  40. data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +155 -0
  41. data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +76 -3
  42. data/spec/cache_spec.rb +2 -52
  43. data/spec/config_parser_spec.rb +27 -13
  44. data/spec/connection_wrapper_spec.rb +5 -2
  45. data/spec/context_spec.rb +163 -100
  46. data/spec/cookie_spec.rb +72 -0
  47. data/spec/middleware_spec.rb +26 -55
  48. data/spec/pool_spec.rb +24 -0
  49. data/spec/proxy_spec.rb +51 -36
  50. data/spec/spec_helper.rb +5 -9
  51. data/spec/strategies/shard_aware_spec.rb +219 -0
  52. data/spec/support/helpers.rb +6 -2
  53. data/spec/support/mock_objects.rb +5 -1
  54. data/spec/support/mysql2_database.yml +1 -0
  55. data/spec/support/mysql2_database_with_custom_errors.yml +5 -0
  56. data/spec/support/postgis_database.yml +15 -0
  57. data/spec/support/postgis_schema.rb +11 -0
  58. data/spec/support/postgresql_database.yml +2 -0
  59. data/spec/support/proxy_extensions.rb +1 -1
  60. data/spec/support/schema.rb +5 -5
  61. data/spec/support/user.rb +5 -0
  62. metadata +28 -9
  63. data/lib/makara/cache/memory_store.rb +0 -28
  64. data/lib/makara/cache/noop_store.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a43f7871351a95b0291a4624bdfded3e1e4bccf3
4
- data.tar.gz: feaf04905d1a7293abd47cf32a0f69f23575c609
2
+ SHA256:
3
+ metadata.gz: 0dae82f5608272a2e365b3f75561d7e0359a646101a54d769d854eb1437c49ef
4
+ data.tar.gz: b9de62fb9f9ef35029c71b32038ca21c05dd3922a4a6b1ed5ff86578fe5e30ef
5
5
  SHA512:
6
- metadata.gz: 06ce4185196b043f4129039a18a55db3f18816ab8af517372193ac28e2cf8517b4dd0abee9970ab012b0a0f2214fd56e42fcd3fce5643d077a8aa3537bbd4635
7
- data.tar.gz: a45e25f35d71242f954d4a5fdeafeb0907399b496d19c9122e227ad04bd0486986ce37e2390877f191a2adc0e7295a37ecade58278c57991b57f6152da3123b1
6
+ metadata.gz: ba51b69a62b36132cdc4654e2207e2b46c0414386111bd3c9a31d8d7ce9960d51cd662f59b6c4fc2194b677c658c7aaff3d85930a3dbbc4cfe289c261d31311d
7
+ data.tar.gz: c0532643db2b517ce248dcead76a01092b9647350671c8794f6b2c19f257fce681579b278ab2c318735a9a6b7f84ebc9aa59ba897a36641645ebd631f1471868
@@ -0,0 +1,36 @@
1
+ name: Publish Public Gem
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - published
7
+
8
+ jobs:
9
+ build:
10
+ name: Build + Publish
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: actions/setup-ruby@v1
16
+ - name: Build
17
+ run: |
18
+ gem build *.gemspec
19
+
20
+ - name: Publish to Github
21
+ run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
26
+ gem push --verbose --key github --host https://rubygems.pkg.github.com/${OWNER} *.gem
27
+ env:
28
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
29
+ OWNER: ${{ github.repository_owner }}
30
+ continue-on-error: true
31
+
32
+ - name: Publish to RubyGems
33
+ run: |
34
+ gem push --verbose *.gem
35
+ env:
36
+ GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_TOKEN}}
@@ -1,33 +1,49 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  cache: bundler
4
+ dist: xenial
4
5
 
5
6
  services:
6
7
  - mysql
7
8
  - postgresql
8
9
 
10
+ addons:
11
+ postgresql: 10
12
+ apt:
13
+ packages:
14
+ - postgresql-10-postgis-2.4
15
+
16
+ before_install:
17
+ - gem install bundler
18
+
9
19
  before_script:
10
20
  - mysql -e 'create database makara_test;'
11
21
  - psql -c 'create database makara_test;' -U postgres
22
+ - psql -c 'create extension postgis;' -U postgres
12
23
 
13
24
  rvm:
14
- - 2.0
15
- - 2.1
16
- - 2.2
25
+ # - 2.0
26
+ # - 2.1
27
+ # - 2.2
17
28
  - 2.3
18
29
  - 2.4
30
+ - 2.5.0
31
+ - 2.6.0
32
+ - 2.7.0
19
33
  - ruby-head
20
34
  - jruby
21
35
 
22
36
  gemfile:
23
- - gemfiles/ar30.gemfile
24
- - gemfiles/ar31.gemfile
25
- - gemfiles/ar32.gemfile
26
- - gemfiles/ar40.gemfile
27
- - gemfiles/ar41.gemfile
28
- - gemfiles/ar42.gemfile
37
+ # - gemfiles/ar30.gemfile
38
+ # - gemfiles/ar31.gemfile
39
+ # - gemfiles/ar32.gemfile
40
+ # - gemfiles/ar40.gemfile
41
+ # - gemfiles/ar41.gemfile
42
+ # - gemfiles/ar42.gemfile
29
43
  - gemfiles/ar50.gemfile
30
44
  - gemfiles/ar51.gemfile
45
+ - gemfiles/ar52.gemfile
46
+ - gemfiles/ar60.gemfile
31
47
  - gemfiles/ar-head.gemfile
32
48
 
33
49
  env:
@@ -42,7 +58,33 @@ matrix:
42
58
  rvm: 2.3
43
59
  - gemfile: gemfiles/ar30.gemfile
44
60
  rvm: 2.4
61
+ - gemfile: gemfiles/ar31.gemfile
62
+ rvm: 2.4
63
+ - gemfile: gemfiles/ar32.gemfile
64
+ rvm: 2.4
65
+ - gemfile: gemfiles/ar40.gemfile
66
+ rvm: 2.4
67
+ - gemfile: gemfiles/ar41.gemfile
68
+ rvm: 2.4
45
69
  - gemfile: gemfiles/ar30.gemfile
70
+ rvm: 2.5.0
71
+ - gemfile: gemfiles/ar31.gemfile
72
+ rvm: 2.5.0
73
+ - gemfile: gemfiles/ar32.gemfile
74
+ rvm: 2.5.0
75
+ - gemfile: gemfiles/ar40.gemfile
76
+ rvm: 2.5.0
77
+ - gemfile: gemfiles/ar41.gemfile
78
+ rvm: 2.5.0
79
+ - gemfile: gemfiles/ar30.gemfile
80
+ rvm: ruby-head
81
+ - gemfile: gemfiles/ar31.gemfile
82
+ rvm: ruby-head
83
+ - gemfile: gemfiles/ar32.gemfile
84
+ rvm: ruby-head
85
+ - gemfile: gemfiles/ar40.gemfile
86
+ rvm: ruby-head
87
+ - gemfile: gemfiles/ar41.gemfile
46
88
  rvm: ruby-head
47
89
  - gemfile: gemfiles/ar50.gemfile
48
90
  rvm: 2.0
@@ -56,12 +98,32 @@ matrix:
56
98
  rvm: 2.1
57
99
  - gemfile: gemfiles/ar51.gemfile
58
100
  rvm: 2.2
101
+ - gemfile: gemfiles/ar52.gemfile
102
+ rvm: 2.0
103
+ - gemfile: gemfiles/ar52.gemfile
104
+ rvm: 2.1
105
+ - gemfile: gemfiles/ar52.gemfile
106
+ rvm: 2.2
107
+ - gemfile: gemfiles/ar60.gemfile
108
+ rvm: 2.0
109
+ - gemfile: gemfiles/ar60.gemfile
110
+ rvm: 2.1
111
+ - gemfile: gemfiles/ar60.gemfile
112
+ rvm: 2.2
113
+ - gemfile: gemfiles/ar60.gemfile
114
+ rvm: 2.3
115
+ - gemfile: gemfiles/ar60.gemfile
116
+ rvm: 2.4
59
117
  - gemfile: gemfiles/ar-head.gemfile
60
118
  rvm: 2.0
61
119
  - gemfile: gemfiles/ar-head.gemfile
62
120
  rvm: 2.1
63
121
  - gemfile: gemfiles/ar-head.gemfile
64
122
  rvm: 2.2
123
+ - gemfile: gemfiles/ar-head.gemfile
124
+ rvm: 2.3
125
+ - gemfile: gemfiles/ar-head.gemfile
126
+ rvm: 2.4
65
127
  allow_failures:
66
128
  - gemfile: gemfiles/ar-head.gemfile
67
129
  - rvm: ruby-head
@@ -1,63 +1,122 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## v0.5.0 - 2021-01-08
5
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.4.1...v0.4.2)
6
+ - Replace deprecated URI.unescape with CGI.unescape [#252](https://github.com/instacart/makara/pull/252) Kevin Robatel
7
+ - Override equality operator for ActiveRecord connection wrapper [#269](https://github.com/instacart/makara/pull/269) Praveen Burgu
8
+ - Handle blacklisted connections in master pool while in transaction [#267] (https://github.com/instacart/makara/pull/267) Praveen Burgu
9
+ - Handle ActiveRecord connection pools correctly [#267] (https://github.com/instacart/makara/pull/267) Praveen Burgu
10
+ - Add preliminary support for sharded databases [#267] (https://github.com/instacart/makara/pull/267) Praveen Burgu
11
+ - Fix ActiveRecord connection pool exhaustion [#268] (https://github.com/instacart/makara/pull/268) Praveen Burgu
12
+ - Drop support for Ruby 2.0, 2.1 and 2.2 [#267] (https://github.com/instacart/makara/pull/267) Praveen Burgu
13
+ - Drop support ActiveRecord 3.x and 4.x [#267] (https://github.com/instacart/makara/pull/267) Praveen Burgu
14
+ - Set up automatic publishing to Github and Rubygems [#275](https://github.com/instacart/makara/pull/275) Matt Larraz
15
+
16
+
17
+ ## v0.4.1 - 2019-03-25
18
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.4.0...v0.4.1)
19
+
20
+ - Fix crash by requiring makara in the adapter [#54](https://github.com/instacart/makara/pull/54) Eric Saxby
21
+ - Add connection logging in non-Rails enviroments [#223](https://github.com/instacart/makara/pull/223) Andrew Kane
22
+
23
+ ## v0.4.0 - 2018-04-01
24
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.10...v0.4.0)
25
+
26
+ 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.
27
+ - Implement stickiness for the duration of `master_ttl` via cookies [#194](https://github.com/instacart/makara/pull/194) Rosa Gutierrez
28
+
29
+
30
+ ## v0.3.10 - 2018-03-20
31
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.9...v0.3.10)
32
+
33
+ Fixed
34
+ - Send nextval queries to master and show queries to replicas for Postgres [#173](https://github.com/instacart/makara/pull/173) Andrew Kane
35
+ - Fixes can't add a new key into hash during iteration error [#174](https://github.com/instacart/makara/pull/174) Andrew Kane
36
+ - Fix: an application freezes when a slave is down [#180](https://github.com/instacart/makara/pull/180) Alexey P
37
+ - Allow SELECTs that use common table expressions to go to replicas [#184](https://github.com/instacart/makara/pull/184) Andrew Kane
38
+ - Send advisory lock requests to the master [#198](https://github.com/instacart/makara/pull/198) George Claghorn
39
+ - Postgres exists query [#199](https://github.com/instacart/makara/pull/199) Brian Leonard
40
+
41
+ Documentation and Test
42
+ - Clarify README's "What goes where" [#187](https://github.com/instacart/makara/pull/187) Jan Sandbrink
43
+ - Fix loading fixtures in Rails 5.2 [#192](https://github.com/instacart/makara/pull/192) George Claghorn
44
+ - Travis Upgrade [#199](https://github.com/instacart/makara/pull/199) Brian Leonard
45
+
46
+ ## v0.3.9 - 2017-08-14
47
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.8...v0.3.9)
48
+
49
+ Changed
50
+ - Add postgis support [#118](https://github.com/instacart/makara/pull/118) Kevin Bacha
51
+
52
+ ## v0.3.8 - 2017-07-11
53
+
54
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.7...v0.3.8)
55
+
56
+ Changed
57
+ - Rails 5.1 compatibility [#150](https://github.com/instacart/makara/pull/150) Jeremy Daer
58
+ - Minimize redundant context cache requests [#157](https://github.com/instacart/makara/issues/157) Greg Patrick
59
+ - thread-local cache for previous context stickiness [#158](https://github.com/instacart/makara/issues/158) Jeremy Daer
60
+ - Configurable cookie options [#159](https://github.com/instacart/makara/pull/159) Jeremy Daer
61
+ - Test against Rails 5.x and Ruby 2.x [#160](https://github.com/instacart/makara/pull/160) Jeremy Daer
62
+
4
63
  ## v0.3.7 - 2016-09-22
5
64
 
6
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.6...v0.3.7)
65
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.6...v0.3.7)
7
66
 
8
67
  Changed
9
68
 
10
- - Fix the hierarchy of the config file [#116](https://github.com/taskrabbit/makara/pull/116) Kevin Bacha
11
- - "Disable blacklist" parameter [#134](https://github.com/taskrabbit/makara/pull/134) Alex Tonkonozhenko
12
- - Fixes bug in `without_sticking` [#96](https://github.com/taskrabbit/makara/pull/96) Brian Leonard
13
- - Always stick inside transactions [#96](https://github.com/taskrabbit/makara/pull/96) Brian Leonard
14
- - Rails 5 support [#122](https://github.com/taskrabbit/makara/pull/122) Jonny McAllister
69
+ - Fix the hierarchy of the config file [#116](https://github.com/instacart/makara/pull/116) Kevin Bacha
70
+ - "Disable blacklist" parameter [#134](https://github.com/instacart/makara/pull/134) Alex Tonkonozhenko
71
+ - Fixes bug in `without_sticking` [#96](https://github.com/instacart/makara/pull/96) Brian Leonard
72
+ - Always stick inside transactions [#96](https://github.com/instacart/makara/pull/96) Brian Leonard
73
+ - Rails 5 support [#122](https://github.com/instacart/makara/pull/122) Jonny McAllister
15
74
 
16
75
  ## v0.3.6 - 2016-04-21
17
76
 
18
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.5...v0.3.6)
77
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.5...v0.3.6)
19
78
 
20
79
  Changed
21
80
 
22
- - Allow different strategies such as `priority` and `round_robin` for pools [#105](https://github.com/taskrabbit/makara/pull/105) Brian Leonard
81
+ - Allow different strategies such as `priority` and `round_robin` for pools [#105](https://github.com/instacart/makara/pull/105) Brian Leonard
23
82
 
24
83
 
25
84
  ## v0.3.5 - 2016-01-08
26
85
 
27
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.4.rc1...v0.3.5)
86
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.4.rc1...v0.3.5)
28
87
 
29
88
  Changed
30
89
 
31
- - Raise `Makara::Errors::AllConnectionsBlacklisted` on timeout. [#104](https://github.com/taskrabbit/makara/pull/104) Brian Leonard
90
+ - Raise `Makara::Errors::AllConnectionsBlacklisted` on timeout. [#104](https://github.com/instacart/makara/pull/104) Brian Leonard
32
91
 
33
92
  ## v0.3.4.rc1 - 2016-01-06
34
93
 
35
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.3...v0.3.4.rc1)
94
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.3...v0.3.4.rc1)
36
95
 
37
96
  Added
38
97
 
39
- - Add `url` to database connections configurations. [#93](https://github.com/taskrabbit/makara/pull/93) Benjamin Fleischer
98
+ - Add `url` to database connections configurations. [#93](https://github.com/instacart/makara/pull/93) Benjamin Fleischer
40
99
 
41
100
  Changed
42
101
 
43
- - Improve Postgresql compatibility and failover support, also fix [#78](https://github.com/taskrabbit/makara/issues/78), [#79](https://github.com/taskrabbit/makara/issues/79). [#87](https://github.com/taskrabbit/makara/pull/87) Vlad
44
- - Update README: Specify newrelic_rpm gem versions that will have the performance issue. [#95](https://github.com/taskrabbit/makara/pull/95) Benjamin Fleischer
102
+ - 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
103
+ - Update README: Specify newrelic_rpm gem versions that will have the performance issue. [#95](https://github.com/instacart/makara/pull/95) Benjamin Fleischer
45
104
 
46
105
  ## v0.3.3 - 2015-05-20
47
106
 
48
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.2...v0.3.3)
107
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.2...v0.3.3)
49
108
 
50
109
  Changed
51
110
 
52
- - 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/taskrabbit/makara/issues/83). [#84](https://github.com/taskrabbit/makara/pull/84) Matt Camuto
111
+ - 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
53
112
 
54
113
  ## v0.3.2 - 2015-05-16
55
114
 
56
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.1...v0.3.2)
115
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.1...v0.3.2)
57
116
 
58
117
  Fixed
59
118
 
60
- - Fix a `ArgumentError: not delegated` error for rails 3. [#82](https://github.com/taskrabbit/makara/pull/82) Eric Saxby
119
+ - Fix a `ArgumentError: not delegated` error for rails 3. [#82](https://github.com/instacart/makara/pull/82) Eric Saxby
61
120
 
62
121
  Changed
63
122
 
@@ -65,7 +124,7 @@ Changed
65
124
 
66
125
  ## v0.3.1 - 2015-05-08
67
126
 
68
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.0...v0.3.1)
127
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.0...v0.3.1)
69
128
 
70
129
  Changed
71
130
 
@@ -75,21 +134,21 @@ Changed
75
134
 
76
135
  ## v0.3.0 - 2015-04-27
77
136
 
78
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.0.rc3...v0.3.0)
137
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.0.rc3...v0.3.0)
79
138
 
80
139
  Changed
81
140
 
82
- - 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/taskrabbit/makara/pull/76) Andrew Kane
141
+ - 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
83
142
 
84
143
  Fixed
85
144
 
86
- - Fix an issue for postgres that would route all queries to master. [#72](https://github.com/taskrabbit/makara/pull/72) Kali Donovan
87
- - Fix an edge case which would cause SET operations to send to all connections([#70](https://github.com/taskrabbit/makara/issues/70)). [#80](https://github.com/taskrabbit/makara/pull/80) Michael Amor Righi
88
- - Fix performance regression with certain verions of [newrelic/rpm](https://github.com/newrelic/rpm)([#59](https://github.com/taskrabbit/makara/issues/59)). [#75](https://github.com/taskrabbit/makara/pull/75) Mike Nelson
145
+ - Fix an issue for postgres that would route all queries to master. [#72](https://github.com/instacart/makara/pull/72) Kali Donovan
146
+ - 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
147
+ - 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
89
148
 
90
149
  ## 0.3.0.rc3 - 2014-09-02[YANKED]
91
150
 
92
- [Full Changelog](https://github.com/taskrabbit/makara/compare/v0.3.0.rc2...v0.3.0.rc3)
151
+ [Full Changelog](https://github.com/instacart/makara/compare/v0.3.0.rc2...v0.3.0.rc3)
93
152
 
94
153
  Added
95
154
  - Allow bypassing of stickiness
data/Gemfile CHANGED
@@ -8,11 +8,12 @@ gem 'rspec'
8
8
  gem 'timecop'
9
9
  gem 'byebug', :platform => :ruby
10
10
  gem 'ruby-debug', :platform => :jruby
11
- gem 'rack', '1.6.0'
11
+ gem 'rack', '2.2.3'
12
12
 
13
13
  gem 'mysql2', :platform => :ruby
14
- gem 'pg', :platform => :ruby
14
+ gem 'pg', '0.21.0', :platform => :ruby
15
+ gem 'activerecord-postgis-adapter', :platform => :ruby
16
+ gem 'rgeo', :platform => :ruby
15
17
 
16
18
  gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
17
19
  gem 'activerecord-jdbcpostgresql-adapter', :platform => :jruby
18
-
data/README.md CHANGED
@@ -6,14 +6,6 @@
6
6
 
7
7
  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
8
 
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
9
  ## Installation
18
10
 
19
11
  Use the current version of the gem from [rubygems](https://rubygems.org/gems/makara) in your `Gemfile`.
@@ -61,40 +53,50 @@ This implementation will send any request not like "SELECT..." to a master conne
61
53
 
62
54
  Makara comes with a config parser which will handle providing subconfigs to the `connection_for` method. Check out the ActiveRecord database.yml example below for more info.
63
55
 
64
- ### Context
56
+ ### Stickiness Context
65
57
 
66
- Makara handles stickyness by keeping track of a context (sha). In a multi-instance environment it persists a context in a cache. If Rails is present it will automatically use Rails.cache. You can provide any kind of store as long as it responds to the methods required in [lib/makara/cache.rb](lib/makara/cache.rb).
58
+ Makara handles stickiness by keeping track of which proxies are stuck at any given moment. The context is basically a mapping of proxy ids to the timestamp until which they are stuck.
67
59
 
68
- ```ruby
69
- Makara::Cache.store = MyRedisCacheStore.new
70
- ```
60
+ 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.
61
+
62
+ #### Stickiness Impact
63
+
64
+ 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.
65
+
66
+ 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.
71
67
 
72
- To handle persistence of context across requests in a Rack app, makara provides a middleware. It lays a cookie named `_mkra_ctxt` which contains the current master context. If the next request is executed before the cookie expires, master will be used. If something occurs which naturally requires master on the second request, the context is changed and stored again.
68
+ #### Releasing stuck connections (clearing context)
73
69
 
74
- #### Changing Context
70
+ If you need to clear the current context, releasing any stuck connections, all you have to do is:
75
71
 
76
- If you need to change the makara context, releasing any stuck connections, all you have to do is:
72
+ ```ruby
73
+ Makara::Context.release_all
74
+ ```
77
75
 
76
+ You can also clear stuck connections for a specific proxy:
78
77
  ```ruby
79
- ctx = Makara::Context.generate # or any unique sha
80
- Makara::Context.set_current ctx
78
+ Makara::Context.release(proxy_id)
79
+ Makara::Context.release('mysql_main')
80
+ Makara::Context.release('redis')
81
+ ...
81
82
  ```
82
83
 
83
84
  A context is local to the curent thread of execution. This will allow you to stick to master safely in a single thread
84
85
  in systems such as sidekiq, for instance.
85
86
 
86
87
 
87
- ### Forcing Master
88
+ #### Forcing Master
88
89
 
89
90
  If you need to force master in your app then you can simply invoke stick_to_master! on your connection:
90
91
 
91
92
  ```ruby
92
- write_to_cache = true # or false
93
- proxy.stick_to_master!(write_to_cache)
93
+ persist = true # or false, it's true by default
94
+ proxy.stick_to_master!(persist)
94
95
  ```
95
96
 
97
+ It'll keep the proxy stuck to master for the current request, and if `persist = true` (default), it'll be also stored in the context for subsequent requests, keeping the proxy stuck up to the duration of `master_ttl` configured for the proxy.
96
98
 
97
- ### Skipping the Stickiness
99
+ #### Skipping the Stickiness
98
100
 
99
101
  If you're using the `sticky: true` configuration and you find yourself in a situation where you need to write information through the proxy but you don't want the context to be stuck to master, you should use a `without_sticking` block:
100
102
 
@@ -120,7 +122,13 @@ By creating a makara database adapter which simply acts as a proxy we avoid any
120
122
 
121
123
  ### What goes where?
122
124
 
123
- Any `SELECT` statements will execute against your slave(s), anything else will go to master. The only edge case is `SET` operations which are sent to all connections. Execution of specific methods such as `connect!`, `disconnect!`, and `clear_cache!` are invoked on all underlying connections.
125
+ In general: Any `SELECT` statements will execute against your slave(s), anything else will go to master.
126
+
127
+ There are some edge cases:
128
+ * `SET` operations will be sent to all connections
129
+ * Execution of specific methods such as `connect!`, `disconnect!`, and `clear_cache!` are invoked on all underlying connections
130
+ * 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)
131
+ * Locking reads (e.g. `SELECT ... FOR UPDATE`) will always be sent to the master
124
132
 
125
133
  ### Errors / blacklisting
126
134
 
@@ -139,6 +147,8 @@ production:
139
147
  # add a makara subconfig
140
148
  makara:
141
149
 
150
+ # optional id to identify the proxy with this configuration for stickiness
151
+ id: mysql
142
152
  # the following are default values
143
153
  blacklist_duration: 5
144
154
  master_ttl: 5
@@ -161,11 +171,13 @@ Let's break this down a little bit. At the top level of your config you have the
161
171
  Following the adapter choice is all the standard configurations (host, port, retry, database, username, password, etc). With all the standard configurations provided, you can now provide the makara subconfig.
162
172
 
163
173
  The makara subconfig sets up the proxy with a few of its own options, then provides the connection list. The makara options are:
174
+ * id - an identifier for the proxy, used for sticky behaviour and context. The default is to use a MD5 hash of the configuration contents, so if you are setting `sticky` to true, it's a good idea to also set an `id`. Otherwise any stuck connections will be cleared if the configuration changes (as the default MD5 hash id would change as well)
164
175
  * blacklist_duration - the number of seconds a node is blacklisted when a connection failure occurs
165
176
  * disable_blacklist - do not blacklist node at any error, useful in case of one master
166
177
  * sticky - if a node should be stuck to once it's used during a specific context
167
178
  * 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.
179
+ * 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.
180
+ * 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
181
  * 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
182
 
171
183
  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.
@@ -268,16 +280,7 @@ def handle_request_after_third_party_record_creation
268
280
  end
269
281
  ```
270
282
 
271
- Similarly, if you have a third party service which will conduct a generic request against your Rack app, you can force master via a query param:
272
-
273
- ```ruby
274
- def send_url_to_third_party
275
- context = Makara::Context.get_current
276
- ThirdParty.read_from_here!("http://mysite.com/path/to/resource?_mkra_ctxt=#{context}")
277
- end
278
- ```
279
-
280
283
  ## Todo
281
284
 
282
- * Cookie based cache store?
285
+ * Support for providing context as query param
283
286
  * More real world examples