dalli 2.7.2 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +231 -0
  3. data/Gemfile +14 -5
  4. data/LICENSE +1 -1
  5. data/README.md +33 -201
  6. data/lib/dalli/cas/client.rb +2 -57
  7. data/lib/dalli/client.rb +259 -254
  8. data/lib/dalli/compressor.rb +13 -2
  9. data/lib/dalli/key_manager.rb +121 -0
  10. data/lib/dalli/options.rb +7 -7
  11. data/lib/dalli/pid_cache.rb +40 -0
  12. data/lib/dalli/pipelined_getter.rb +177 -0
  13. data/lib/dalli/protocol/base.rb +239 -0
  14. data/lib/dalli/protocol/binary/request_formatter.rb +117 -0
  15. data/lib/dalli/protocol/binary/response_header.rb +36 -0
  16. data/lib/dalli/protocol/binary/response_processor.rb +239 -0
  17. data/lib/dalli/protocol/binary/sasl_authentication.rb +60 -0
  18. data/lib/dalli/protocol/binary.rb +173 -0
  19. data/lib/dalli/protocol/connection_manager.rb +254 -0
  20. data/lib/dalli/protocol/meta/key_regularizer.rb +31 -0
  21. data/lib/dalli/protocol/meta/request_formatter.rb +121 -0
  22. data/lib/dalli/protocol/meta/response_processor.rb +211 -0
  23. data/lib/dalli/protocol/meta.rb +178 -0
  24. data/lib/dalli/protocol/response_buffer.rb +54 -0
  25. data/lib/dalli/protocol/server_config_parser.rb +86 -0
  26. data/lib/dalli/protocol/ttl_sanitizer.rb +45 -0
  27. data/lib/dalli/protocol/value_compressor.rb +85 -0
  28. data/lib/dalli/protocol/value_marshaller.rb +59 -0
  29. data/lib/dalli/protocol/value_serializer.rb +91 -0
  30. data/lib/dalli/protocol.rb +8 -0
  31. data/lib/dalli/ring.rb +97 -86
  32. data/lib/dalli/server.rb +4 -694
  33. data/lib/dalli/servers_arg_normalizer.rb +54 -0
  34. data/lib/dalli/socket.rb +122 -80
  35. data/lib/dalli/version.rb +5 -1
  36. data/lib/dalli.rb +45 -14
  37. data/lib/rack/session/dalli.rb +162 -42
  38. metadata +40 -96
  39. data/Performance.md +0 -42
  40. data/Rakefile +0 -42
  41. data/dalli.gemspec +0 -29
  42. data/lib/action_dispatch/middleware/session/dalli_store.rb +0 -81
  43. data/lib/active_support/cache/dalli_store.rb +0 -363
  44. data/lib/dalli/railtie.rb +0 -7
  45. data/test/benchmark_test.rb +0 -242
  46. data/test/helper.rb +0 -55
  47. data/test/memcached_mock.rb +0 -121
  48. data/test/sasldb +0 -1
  49. data/test/test_active_support.rb +0 -439
  50. data/test/test_cas_client.rb +0 -107
  51. data/test/test_compressor.rb +0 -53
  52. data/test/test_dalli.rb +0 -625
  53. data/test/test_encoding.rb +0 -32
  54. data/test/test_failover.rb +0 -128
  55. data/test/test_network.rb +0 -54
  56. data/test/test_rack_session.rb +0 -341
  57. data/test/test_ring.rb +0 -85
  58. data/test/test_sasl.rb +0 -110
  59. data/test/test_serializer.rb +0 -30
  60. data/test/test_server.rb +0 -80
@@ -1,128 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'failover' do
4
-
5
- describe 'timeouts' do
6
- it 'not lead to corrupt sockets' do
7
- memcached(29125) do
8
- dc = Dalli::Client.new ['localhost:29125']
9
- begin
10
- Timeout.timeout 0.01 do
11
- 1_000.times do
12
- dc.set("test_123", {:test => "123"})
13
- end
14
- flunk("Did not timeout")
15
- end
16
- rescue Timeout::Error
17
- end
18
-
19
- assert_equal({:test => '123'}, dc.get("test_123"))
20
- end
21
- end
22
- end
23
-
24
-
25
- describe 'assuming some bad servers' do
26
-
27
- it 'silently reconnect if server hiccups' do
28
- memcached(29125) do
29
- dc = Dalli::Client.new ['localhost:29125']
30
- dc.set 'foo', 'bar'
31
- foo = dc.get 'foo'
32
- assert_equal foo, 'bar'
33
-
34
- memcached_kill(29125)
35
- memcached(29125) do
36
-
37
- foo = dc.get 'foo'
38
- assert_nil foo
39
-
40
- memcached_kill(29125)
41
- end
42
- end
43
- end
44
-
45
- it 'handle graceful failover' do
46
- memcached(29125) do
47
- memcached(29126) do
48
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
49
- dc.set 'foo', 'bar'
50
- foo = dc.get 'foo'
51
- assert_equal foo, 'bar'
52
-
53
- memcached_kill(29125)
54
-
55
- dc.set 'foo', 'bar'
56
- foo = dc.get 'foo'
57
- assert_equal foo, 'bar'
58
-
59
- memcached_kill(29126)
60
-
61
- assert_raises Dalli::RingError, :message => "No server available" do
62
- dc.set 'foo', 'bar'
63
- end
64
- end
65
- end
66
- end
67
-
68
- it 'handle them gracefully in get_multi' do
69
- memcached(29125) do
70
- memcached(29126) do
71
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
72
- dc.set 'a', 'a1'
73
- result = dc.get_multi ['a']
74
- assert_equal result, {'a' => 'a1'}
75
-
76
- memcached_kill(29125)
77
-
78
- result = dc.get_multi ['a']
79
- assert_equal result, {'a' => 'a1'}
80
- end
81
- end
82
- end
83
-
84
- it 'handle graceful failover in get_multi' do
85
- memcached(29125) do
86
- memcached(29126) do
87
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
88
- dc.set 'foo', 'foo1'
89
- dc.set 'bar', 'bar1'
90
- result = dc.get_multi ['foo', 'bar']
91
- assert_equal result, {'foo' => 'foo1', 'bar' => 'bar1'}
92
-
93
- memcached_kill(29125)
94
-
95
- dc.set 'foo', 'foo1'
96
- dc.set 'bar', 'bar1'
97
- result = dc.get_multi ['foo', 'bar']
98
- assert_equal result, {'foo' => 'foo1', 'bar' => 'bar1'}
99
-
100
- memcached_kill(29126)
101
-
102
- result = dc.get_multi ['foo', 'bar']
103
- assert_equal result, {}
104
- end
105
- end
106
- end
107
-
108
- it 'stats it still properly report' do
109
- memcached(29125) do
110
- memcached(29126) do
111
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
112
- result = dc.stats
113
- assert_instance_of Hash, result['localhost:29125']
114
- assert_instance_of Hash, result['localhost:29126']
115
-
116
- memcached_kill(29125)
117
-
118
- dc = Dalli::Client.new ['localhost:29125', 'localhost:29126']
119
- result = dc.stats
120
- assert_instance_of NilClass, result['localhost:29125']
121
- assert_instance_of Hash, result['localhost:29126']
122
-
123
- memcached_kill(29126)
124
- end
125
- end
126
- end
127
- end
128
- end
data/test/test_network.rb DELETED
@@ -1,54 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'Network' do
4
-
5
- describe 'assuming a bad network' do
6
-
7
- it 'handle no server available' do
8
- assert_raises Dalli::RingError, :message => "No server available" do
9
- dc = Dalli::Client.new 'localhost:19333'
10
- dc.get 'foo'
11
- end
12
- end
13
-
14
- describe 'with a fake server' do
15
- it 'handle connection reset' do
16
- memcached_mock(lambda {|sock| sock.close }) do
17
- assert_raises Dalli::RingError, :message => "No server available" do
18
- dc = Dalli::Client.new('localhost:19123')
19
- dc.get('abc')
20
- end
21
- end
22
- end
23
-
24
- it 'handle malformed response' do
25
- memcached_mock(lambda {|sock| sock.write('123') }) do
26
- assert_raises Dalli::RingError, :message => "No server available" do
27
- dc = Dalli::Client.new('localhost:19123')
28
- dc.get('abc')
29
- end
30
- end
31
- end
32
-
33
- it 'handle connect timeouts' do
34
- memcached_mock(lambda {|sock| sleep(0.6); sock.close }, :delayed_start) do
35
- assert_raises Dalli::RingError, :message => "No server available" do
36
- dc = Dalli::Client.new('localhost:19123')
37
- dc.get('abc')
38
- end
39
- end
40
- end
41
-
42
- it 'handle read timeouts' do
43
- memcached_mock(lambda {|sock| sleep(0.6); sock.write('giraffe') }) do
44
- assert_raises Dalli::RingError, :message => "No server available" do
45
- dc = Dalli::Client.new('localhost:19123')
46
- dc.get('abc')
47
- end
48
- end
49
- end
50
-
51
- end
52
-
53
- end
54
- end
@@ -1,341 +0,0 @@
1
- require 'helper'
2
-
3
- require 'rack/session/dalli'
4
- require 'rack/lint'
5
- require 'rack/mock'
6
- require 'thread'
7
-
8
- describe Rack::Session::Dalli do
9
- Rack::Session::Dalli::DEFAULT_OPTIONS[:memcache_server] = 'localhost:19129'
10
-
11
- before do
12
- memcached(19129) do
13
- end
14
-
15
- # test memcache connection
16
- Rack::Session::Dalli.new(incrementor)
17
- end
18
-
19
- let(:session_key) { Rack::Session::Dalli::DEFAULT_OPTIONS[:key] }
20
- let(:session_match) do
21
- /#{session_key}=([0-9a-fA-F]+);/
22
- end
23
- let(:incrementor_proc) do
24
- lambda do |env|
25
- env["rack.session"]["counter"] ||= 0
26
- env["rack.session"]["counter"] += 1
27
- Rack::Response.new(env["rack.session"].inspect).to_a
28
- end
29
- end
30
- let(:drop_session) do
31
- Rack::Lint.new(proc do |env|
32
- env['rack.session.options'][:drop] = true
33
- incrementor_proc.call(env)
34
- end)
35
- end
36
- let(:renew_session) do
37
- Rack::Lint.new(proc do |env|
38
- env['rack.session.options'][:renew] = true
39
- incrementor_proc.call(env)
40
- end)
41
- end
42
- let(:defer_session) do
43
- Rack::Lint.new(proc do |env|
44
- env['rack.session.options'][:defer] = true
45
- incrementor_proc.call(env)
46
- end)
47
- end
48
- let(:skip_session) do
49
- Rack::Lint.new(proc do |env|
50
- env['rack.session.options'][:skip] = true
51
- incrementor_proc.call(env)
52
- end)
53
- end
54
- let(:incrementor) { Rack::Lint.new(incrementor_proc) }
55
-
56
- it "faults on no connection" do
57
- assert_raises Dalli::RingError do
58
- Rack::Session::Dalli.new(incrementor, :memcache_server => 'nosuchserver')
59
- end
60
- end
61
-
62
- it "connects to existing server" do
63
- assert_silent do
64
- rsd = Rack::Session::Dalli.new(incrementor, :namespace => 'test:rack:session')
65
- rsd.pool.set('ping', '')
66
- end
67
- end
68
-
69
- it "passes options to MemCache" do
70
- rsd = Rack::Session::Dalli.new(incrementor, :namespace => 'test:rack:session')
71
- assert_equal('test:rack:session', rsd.pool.instance_eval { @options[:namespace] })
72
- end
73
-
74
- it "creates a new cookie" do
75
- rsd = Rack::Session::Dalli.new(incrementor)
76
- res = Rack::MockRequest.new(rsd).get("/")
77
- assert res["Set-Cookie"].include?("#{session_key}=")
78
- assert_equal '{"counter"=>1}', res.body
79
- end
80
-
81
- it "determines session from a cookie" do
82
- rsd = Rack::Session::Dalli.new(incrementor)
83
- req = Rack::MockRequest.new(rsd)
84
- res = req.get("/")
85
- cookie = res["Set-Cookie"]
86
- assert_equal '{"counter"=>2}', req.get("/", "HTTP_COOKIE" => cookie).body
87
- assert_equal '{"counter"=>3}', req.get("/", "HTTP_COOKIE" => cookie).body
88
- end
89
-
90
- it "determines session only from a cookie by default" do
91
- rsd = Rack::Session::Dalli.new(incrementor)
92
- req = Rack::MockRequest.new(rsd)
93
- res = req.get("/")
94
- sid = res["Set-Cookie"][session_match, 1]
95
- assert_equal '{"counter"=>1}', req.get("/?rack.session=#{sid}").body
96
- assert_equal '{"counter"=>1}', req.get("/?rack.session=#{sid}").body
97
- end
98
-
99
- it "determines session from params" do
100
- rsd = Rack::Session::Dalli.new(incrementor, :cookie_only => false)
101
- req = Rack::MockRequest.new(rsd)
102
- res = req.get("/")
103
- sid = res["Set-Cookie"][session_match, 1]
104
- assert_equal '{"counter"=>2}', req.get("/?rack.session=#{sid}").body
105
- assert_equal '{"counter"=>3}', req.get("/?rack.session=#{sid}").body
106
- end
107
-
108
- it "survives nonexistant cookies" do
109
- bad_cookie = "rack.session=blarghfasel"
110
- rsd = Rack::Session::Dalli.new(incrementor)
111
- res = Rack::MockRequest.new(rsd).
112
- get("/", "HTTP_COOKIE" => bad_cookie)
113
- assert_equal '{"counter"=>1}', res.body
114
- cookie = res["Set-Cookie"][session_match]
115
- refute_match(/#{bad_cookie}/, cookie)
116
- end
117
-
118
- it "survives nonexistant blank cookies" do
119
- bad_cookie = "rack.session="
120
- rsd = Rack::Session::Dalli.new(incrementor)
121
- res = Rack::MockRequest.new(rsd).
122
- get("/", "HTTP_COOKIE" => bad_cookie)
123
- cookie = res["Set-Cookie"][session_match]
124
- refute_match(/#{bad_cookie}$/, cookie)
125
- end
126
-
127
- it "maintains freshness" do
128
- rsd = Rack::Session::Dalli.new(incrementor, :expire_after => 3)
129
- res = Rack::MockRequest.new(rsd).get('/')
130
- assert res.body.include?('"counter"=>1')
131
- cookie = res["Set-Cookie"]
132
- res = Rack::MockRequest.new(rsd).get('/', "HTTP_COOKIE" => cookie)
133
- assert_equal cookie, res["Set-Cookie"]
134
- assert res.body.include?('"counter"=>2')
135
- puts 'Sleeping to expire session' if $DEBUG
136
- sleep 4
137
- res = Rack::MockRequest.new(rsd).get('/', "HTTP_COOKIE" => cookie)
138
- refute_equal cookie, res["Set-Cookie"]
139
- assert res.body.include?('"counter"=>1')
140
- end
141
-
142
- it "does not send the same session id if it did not change" do
143
- rsd = Rack::Session::Dalli.new(incrementor)
144
- req = Rack::MockRequest.new(rsd)
145
-
146
- res0 = req.get("/")
147
- cookie = res0["Set-Cookie"][session_match]
148
- assert_equal '{"counter"=>1}', res0.body
149
-
150
- res1 = req.get("/", "HTTP_COOKIE" => cookie)
151
- assert_nil res1["Set-Cookie"]
152
- assert_equal '{"counter"=>2}', res1.body
153
-
154
- res2 = req.get("/", "HTTP_COOKIE" => cookie)
155
- assert_nil res2["Set-Cookie"]
156
- assert_equal '{"counter"=>3}', res2.body
157
- end
158
-
159
- it "deletes cookies with :drop option" do
160
- rsd = Rack::Session::Dalli.new(incrementor)
161
- req = Rack::MockRequest.new(rsd)
162
- drop = Rack::Utils::Context.new(rsd, drop_session)
163
- dreq = Rack::MockRequest.new(drop)
164
-
165
- res1 = req.get("/")
166
- session = (cookie = res1["Set-Cookie"])[session_match]
167
- assert_equal '{"counter"=>1}', res1.body
168
-
169
- res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
170
- assert_nil res2["Set-Cookie"]
171
- assert_equal '{"counter"=>2}', res2.body
172
-
173
- res3 = req.get("/", "HTTP_COOKIE" => cookie)
174
- refute_equal session, res3["Set-Cookie"][session_match]
175
- assert_equal '{"counter"=>1}', res3.body
176
- end
177
-
178
- it "provides new session id with :renew option" do
179
- rsd = Rack::Session::Dalli.new(incrementor)
180
- req = Rack::MockRequest.new(rsd)
181
- renew = Rack::Utils::Context.new(rsd, renew_session)
182
- rreq = Rack::MockRequest.new(renew)
183
-
184
- res1 = req.get("/")
185
- session = (cookie = res1["Set-Cookie"])[session_match]
186
- assert_equal '{"counter"=>1}', res1.body
187
-
188
- res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
189
- new_cookie = res2["Set-Cookie"]
190
- new_session = new_cookie[session_match]
191
- refute_equal session, new_session
192
- assert_equal '{"counter"=>2}', res2.body
193
-
194
- res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
195
- assert_equal '{"counter"=>3}', res3.body
196
-
197
- # Old cookie was deleted
198
- res4 = req.get("/", "HTTP_COOKIE" => cookie)
199
- assert_equal '{"counter"=>1}', res4.body
200
- end
201
-
202
- it "omits cookie with :defer option but still updates the state" do
203
- rsd = Rack::Session::Dalli.new(incrementor)
204
- count = Rack::Utils::Context.new(rsd, incrementor)
205
- defer = Rack::Utils::Context.new(rsd, defer_session)
206
- dreq = Rack::MockRequest.new(defer)
207
- creq = Rack::MockRequest.new(count)
208
-
209
- res0 = dreq.get("/")
210
- assert_nil res0["Set-Cookie"]
211
- assert_equal '{"counter"=>1}', res0.body
212
-
213
- res0 = creq.get("/")
214
- res1 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
215
- assert_equal '{"counter"=>2}', res1.body
216
- res2 = dreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
217
- assert_equal '{"counter"=>3}', res2.body
218
- end
219
-
220
- it "omits cookie and state update with :skip option" do
221
- rsd = Rack::Session::Dalli.new(incrementor)
222
- count = Rack::Utils::Context.new(rsd, incrementor)
223
- skip = Rack::Utils::Context.new(rsd, skip_session)
224
- sreq = Rack::MockRequest.new(skip)
225
- creq = Rack::MockRequest.new(count)
226
-
227
- res0 = sreq.get("/")
228
- assert_nil res0["Set-Cookie"]
229
- assert_equal '{"counter"=>1}', res0.body
230
-
231
- res0 = creq.get("/")
232
- res1 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
233
- assert_equal '{"counter"=>2}', res1.body
234
- res2 = sreq.get("/", "HTTP_COOKIE" => res0["Set-Cookie"])
235
- assert_equal '{"counter"=>2}', res2.body
236
- end
237
-
238
- it "updates deep hashes correctly" do
239
- hash_check = proc do |env|
240
- session = env['rack.session']
241
- unless session.include? 'test'
242
- session.update :a => :b, :c => { :d => :e },
243
- :f => { :g => { :h => :i} }, 'test' => true
244
- else
245
- session[:f][:g][:h] = :j
246
- end
247
- [200, {}, [session.inspect]]
248
- end
249
- rsd = Rack::Session::Dalli.new(hash_check)
250
- req = Rack::MockRequest.new(rsd)
251
-
252
- res0 = req.get("/")
253
- session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
254
- ses0 = rsd.pool.get(session_id, true)
255
-
256
- req.get("/", "HTTP_COOKIE" => cookie)
257
- ses1 = rsd.pool.get(session_id, true)
258
-
259
- refute_equal ses0, ses1
260
- end
261
-
262
- # anyone know how to do this better?
263
- it "cleanly merges sessions when multithreaded" do
264
- unless $DEBUG
265
- assert_equal 1, 1 # fake assertion to appease the mighty bacon
266
- next
267
- end
268
- warn 'Running multithread test for Session::Dalli'
269
- rsd = Rack::Session::Dalli.new(incrementor)
270
- req = Rack::MockRequest.new(rsd)
271
-
272
- res = req.get('/')
273
- assert_equal '{"counter"=>1}', res.body
274
- cookie = res["Set-Cookie"]
275
- session_id = cookie[session_match, 1]
276
-
277
- delta_incrementor = lambda do |env|
278
- # emulate disconjoinment of threading
279
- env['rack.session'] = env['rack.session'].dup
280
- Thread.stop
281
- env['rack.session'][(Time.now.usec*rand).to_i] = true
282
- incrementor.call(env)
283
- end
284
- tses = Rack::Utils::Context.new rsd, delta_incrementor
285
- treq = Rack::MockRequest.new(tses)
286
- tnum = rand(7).to_i+5
287
- r = Array.new(tnum) do
288
- Thread.new(treq) do |run|
289
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
290
- end
291
- end.reverse.map{|t| t.run.join.value }
292
- r.each do |request|
293
- assert_equal cookie, request['Set-Cookie']
294
- assert request.body.include?('"counter"=>2')
295
- end
296
-
297
- session = rsd.pool.get(session_id)
298
- assert_equal tnum+1, session.size # counter
299
- assert_equal 2, session['counter'] # meeeh
300
-
301
- tnum = rand(7).to_i+5
302
- r = Array.new(tnum) do |i|
303
- app = Rack::Utils::Context.new rsd, time_delta
304
- req = Rack::MockRequest.new app
305
- Thread.new(req) do |run|
306
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
307
- end
308
- end.reverse.map{|t| t.run.join.value }
309
- r.each do |request|
310
- assert_equal cookie, request['Set-Cookie']
311
- assert request.body.include?('"counter"=>3')
312
- end
313
-
314
- session = rsd.pool.get(session_id)
315
- assert_equal tnum+1, session.size
316
- assert_equal 3, session['counter']
317
-
318
- drop_counter = proc do |env|
319
- env['rack.session'].delete 'counter'
320
- env['rack.session']['foo'] = 'bar'
321
- [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
322
- end
323
- tses = Rack::Utils::Context.new rsd, drop_counter
324
- treq = Rack::MockRequest.new(tses)
325
- tnum = rand(7).to_i+5
326
- r = Array.new(tnum) do
327
- Thread.new(treq) do |run|
328
- run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
329
- end
330
- end.reverse.map{|t| t.run.join.value }
331
- r.each do |request|
332
- assert_equal cookie, request['Set-Cookie']
333
- assert request.body.include?('"foo"=>"bar"')
334
- end
335
-
336
- session = rsd.pool.get(session_id)
337
- assert_equal r.size+1, session.size
338
- assert_nil session['counter']
339
- assert_equal 'bar', session['foo']
340
- end
341
- end
data/test/test_ring.rb DELETED
@@ -1,85 +0,0 @@
1
- require 'helper'
2
-
3
- describe 'Ring' do
4
-
5
- describe 'a ring of servers' do
6
-
7
- it "have the continuum sorted by value" do
8
- servers = [stub(:hostname => "localhost", :port => "11211", :weight => 1),
9
- stub(:hostname => "localhost", :port => "9500", :weight => 1)]
10
- ring = Dalli::Ring.new(servers, {})
11
- previous_value = 0
12
- ring.continuum.each do |entry|
13
- assert entry.value > previous_value
14
- previous_value = entry.value
15
- end
16
- end
17
-
18
- it 'raise when no servers are available/defined' do
19
- ring = Dalli::Ring.new([], {})
20
- assert_raises Dalli::RingError, :message => "No server available" do
21
- ring.server_for_key('test')
22
- end
23
- end
24
-
25
- describe 'containing only a single server' do
26
- it "raise correctly when it's not alive" do
27
- servers = [
28
- Dalli::Server.new("localhost:12345"),
29
- ]
30
- ring = Dalli::Ring.new(servers, {})
31
- assert_raises Dalli::RingError, :message => "No server available" do
32
- ring.server_for_key('test')
33
- end
34
- end
35
-
36
- it "return the server when it's alive" do
37
- servers = [
38
- Dalli::Server.new("localhost:19191"),
39
- ]
40
- ring = Dalli::Ring.new(servers, {})
41
- memcached(19191) do |mc|
42
- ring = mc.send(:ring)
43
- assert_equal ring.servers.first.port, ring.server_for_key('test').port
44
- end
45
- end
46
- end
47
-
48
- describe 'containing multiple servers' do
49
- it "raise correctly when no server is alive" do
50
- servers = [
51
- Dalli::Server.new("localhost:12345"),
52
- Dalli::Server.new("localhost:12346"),
53
- ]
54
- ring = Dalli::Ring.new(servers, {})
55
- assert_raises Dalli::RingError, :message => "No server available" do
56
- ring.server_for_key('test')
57
- end
58
- end
59
-
60
- it "return an alive server when at least one is alive" do
61
- servers = [
62
- Dalli::Server.new("localhost:12346"),
63
- Dalli::Server.new("localhost:19191"),
64
- ]
65
- ring = Dalli::Ring.new(servers, {})
66
- memcached(19191) do |mc|
67
- ring = mc.send(:ring)
68
- assert_equal ring.servers.first.port, ring.server_for_key('test').port
69
- end
70
- end
71
- end
72
-
73
- it 'detect when a dead server is up again' do
74
- memcached(19997) do
75
- down_retry_delay = 0.5
76
- dc = Dalli::Client.new(['localhost:19997', 'localhost:19998'], :down_retry_delay => down_retry_delay)
77
- assert_equal 1, dc.stats.values.compact.count
78
-
79
- memcached(19998) do
80
- assert_equal 2, dc.stats.values.compact.count
81
- end
82
- end
83
- end
84
- end
85
- end