makara 0.3.10 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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