makara 0.3.10 → 0.4.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.
@@ -41,20 +41,57 @@ describe Makara::Proxy do
41
41
  expect(proxy.irespondtothis).to eq('hello!')
42
42
  end
43
43
 
44
- it 'should use master if manually forced' do
45
- proxy = klass.new(config(1, 2))
44
+ describe '#stick_to_master' do
45
+ let(:proxy) { klass.new(config(1, 2)) }
46
46
 
47
- expect(proxy.master_for?('select * from users')).to eq(false)
47
+ it 'should use master if manually forced' do
48
+ expect(proxy.master_for?('select * from users')).to eq(false)
48
49
 
49
- proxy.stick_to_master!
50
+ proxy.stick_to_master!
50
51
 
51
- expect(proxy.master_for?('select * from users')).to eq(true)
52
- end
52
+ expect(proxy.master_for?('select * from users')).to eq(true)
53
+ end
54
+
55
+ it 'should persist stickiness by default' do
56
+ now = Time.now
57
+ proxy.stick_to_master!
58
+
59
+ next_context = Makara::Context.next
60
+ expect(next_context[proxy.id]).to be >= (now + 5).to_f
61
+
62
+ proxy = klass.new(config(1, 2))
63
+ expect(proxy.master_for?('select * from users')).to eq(true)
64
+ end
53
65
 
66
+ it 'optionally skips stickiness persistence, so it applies only to the current request' do
67
+ now = Time.now
68
+ proxy.stick_to_master!(false)
69
+
70
+ expect(proxy.master_for?('select * from users')).to eq(true)
71
+ next_context = Makara::Context.next
72
+ expect(next_context).to be_nil # Nothing to persist, so context is empty
73
+
74
+ proxy = klass.new(config(1, 2))
75
+ expect(proxy.master_for?('select * from users')).to eq(false)
76
+ end
77
+
78
+ it 'supports a float master_ttl for stickiness duration' do
79
+ now = Time.now
80
+ config = config(1, 2).dup
81
+ config[:makara][:master_ttl] = 0.5
82
+ proxy = klass.new(config)
83
+
84
+ proxy.stick_to_master!
85
+
86
+ next_context = Makara::Context.next
87
+ expect(next_context[proxy.id]).to be >= (now + 0.5).to_f
88
+ expect(next_context[proxy.id]).to be < (now + 1).to_f
89
+ end
90
+ end
54
91
 
55
- context '#appropriate_pool' do
56
92
 
57
- let(:proxy){ klass.new(config(1,1)) }
93
+ describe '#appropriate_pool' do
94
+ let(:proxy) { klass.new(config(1,1)) }
58
95
 
59
96
  it 'should be sticky by default' do
60
97
  expect(proxy.sticky).to eq(true)
@@ -104,41 +141,23 @@ describe Makara::Proxy do
104
141
  expect(proxy.master_for?('select * from users')).to eq(false)
105
142
  end
106
143
 
107
- # if the context changes we should still use master until the previous context is no longer relevant
108
- it 'should release master if the context changes and enough time passes' do
144
+ it "should not release master if it was stuck in the same request (no context changes yet)" do
109
145
  expect(proxy.master_for?('insert into users values (a,b,c)')).to eq(true)
110
146
  expect(proxy.master_for?('select * from users')).to eq(true)
111
147
 
112
- change_context
113
-
114
148
  Timecop.travel Time.now + 10 do
115
- expect(proxy.master_for?('select * from users')).to eq(false)
149
+ # master_ttl has passed but we are still in the same request, so current context
150
+ # is still relevant
151
+ expect(proxy.master_for?('select * from users')).to eq(true)
116
152
  end
117
153
  end
118
154
 
119
- it 'should not release master if the previous context is still relevant' do
155
+ it 'should release master if all stuck connections are released' do
120
156
  expect(proxy.master_for?('insert into users values (a,b,c)')).to eq(true)
121
157
  expect(proxy.master_for?('select * from users')).to eq(true)
122
158
 
123
- roll_context
124
-
125
- proxy.master_for?('select * from users')
126
- expect(proxy.master_for?('select * from users')).to eq(true)
127
-
128
- Timecop.travel Time.now + 10 do
129
- # cache is expired but context has not changed
130
- expect(proxy.master_for?('select * from users')).to eq(true)
131
-
132
- roll_context
159
+ Makara::Context.release_all
133
160
 
134
- expect(proxy.master_for?('select * from users')).to eq(false)
135
- end
136
- end
137
-
138
- it 'should release master if context changes enough' do
139
- expect(proxy.master_for?('insert into users values (a,b,c)')).to eq(true)
140
- roll_context
141
- roll_context
142
161
  expect(proxy.master_for?('select * from users')).to eq(false)
143
162
  end
144
163
 
@@ -188,9 +207,5 @@ describe Makara::Proxy do
188
207
  proxy.slave_pool.connections.each{|con| expect(con._makara_blacklisted?).to eq(false) }
189
208
  proxy.master_pool.connections.each{|con| expect(con._makara_blacklisted?).to eq(false) }
190
209
  end
191
-
192
210
  end
193
-
194
-
195
-
196
211
  end
@@ -2,6 +2,7 @@ require 'active_record'
2
2
  require 'makara'
3
3
  require 'timecop'
4
4
  require 'yaml'
5
+ require 'rack'
5
6
 
6
7
  begin
7
8
  require 'byebug'
@@ -29,20 +30,12 @@ RSpec.configure do |config|
29
30
  config.include SpecHelpers
30
31
 
31
32
  config.before :each do
32
- Makara::Cache.store = :memory
33
33
  change_context
34
34
  allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:should_shuffle?){ false }
35
35
  RSpec::Mocks.space.proxy_for(ActiveRecord::Base).reset # make sure not stubbed in some way
36
36
  end
37
37
 
38
38
  def change_context
39
- Makara::Context.set_previous nil
40
- Makara::Context.set_current nil
39
+ Makara::Context.set_current({})
41
40
  end
42
-
43
- def roll_context
44
- Makara::Context.set_previous Makara::Context.get_current
45
- Makara::Context.set_current Makara::Context.generate
46
- end
47
-
48
41
  end
@@ -15,9 +15,13 @@ module SpecHelpers
15
15
  slaves.times{ connections << {:role => 'slave'} }
16
16
  {
17
17
  :makara => {
18
- :blacklist_duration => 30,
18
+ # Defaults:
19
+ # :master_ttl => 5,
20
+ # :blacklist_duration => 30,
21
+ # :sticky => true
22
+ :id => 'mock_mysql',
19
23
  :connections => connections
20
24
  }
21
25
  }
22
26
  end
23
- end
27
+ end
@@ -11,7 +11,7 @@ class FakeConnection < Struct.new(:config)
11
11
  end
12
12
 
13
13
  def query(content)
14
- []
14
+ config[:name]
15
15
  end
16
16
 
17
17
  def active?
@@ -1,6 +1,6 @@
1
1
  module ProxyExtensions
2
2
 
3
- attr_reader :master_pool, :slave_pool, :master_context, :id
3
+ attr_reader :master_pool, :slave_pool, :id
4
4
 
5
5
  def master_for?(sql)
6
6
  pool_for(sql) == master_pool
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.10
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-20 00:00:00.000000000 Z
11
+ date: 2018-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -61,11 +61,10 @@ files:
61
61
  - lib/active_record/connection_adapters/postgresql_makara_adapter.rb
62
62
  - lib/makara.rb
63
63
  - lib/makara/cache.rb
64
- - lib/makara/cache/memory_store.rb
65
- - lib/makara/cache/noop_store.rb
66
64
  - lib/makara/config_parser.rb
67
65
  - lib/makara/connection_wrapper.rb
68
66
  - lib/makara/context.rb
67
+ - lib/makara/cookie.rb
69
68
  - lib/makara/error_handler.rb
70
69
  - lib/makara/errors/all_connections_blacklisted.rb
71
70
  - lib/makara/errors/blacklist_connection.rb
@@ -91,6 +90,7 @@ files:
91
90
  - spec/config_parser_spec.rb
92
91
  - spec/connection_wrapper_spec.rb
93
92
  - spec/context_spec.rb
93
+ - spec/cookie_spec.rb
94
94
  - spec/middleware_spec.rb
95
95
  - spec/pool_spec.rb
96
96
  - spec/proxy_spec.rb
@@ -142,6 +142,7 @@ test_files:
142
142
  - spec/config_parser_spec.rb
143
143
  - spec/connection_wrapper_spec.rb
144
144
  - spec/context_spec.rb
145
+ - spec/cookie_spec.rb
145
146
  - spec/middleware_spec.rb
146
147
  - spec/pool_spec.rb
147
148
  - spec/proxy_spec.rb
@@ -1,31 +0,0 @@
1
- module Makara
2
- module Cache
3
- class MemoryStore
4
-
5
- def initialize
6
- @data = {}
7
- @mutex = Mutex.new
8
- end
9
-
10
- def read(key)
11
- clean
12
- @data[key].try(:[], 0)
13
- end
14
-
15
- def write(key, value, options = {})
16
- clean
17
- @data[key] = [value, Time.now.to_i + (options[:expires_in] || 5).to_i]
18
- true
19
- end
20
-
21
- protected
22
-
23
- def clean
24
- @mutex.synchronize do
25
- @data.delete_if{|k,v| v[1] <= Time.now.to_i }
26
- end
27
- end
28
-
29
- end
30
- end
31
- end
@@ -1,15 +0,0 @@
1
- module Makara
2
- module Cache
3
- class NoopStore
4
-
5
- def read(key)
6
- nil
7
- end
8
-
9
- def write(key, value, options = {})
10
- nil
11
- end
12
-
13
- end
14
- end
15
- end