fiveruns-memcache-client 1.5.0.3 → 1.5.0.4
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.
- data/History.txt +8 -0
- data/Rakefile +5 -7
- data/ext/crc32/crc32.c +10 -0
- data/lib/memcache.rb +67 -44
- data/test/test_mem_cache.rb +68 -30
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
= 1.5.0.4
|
2
|
+
|
3
|
+
* Get test suite working again (packagethief)
|
4
|
+
* Ruby 1.9 compatiblity fixes (packagethief, mperham)
|
5
|
+
* Consistently return server responses and check for errors (packagethief)
|
6
|
+
* Properly calculate CRC in Ruby 1.9 strings (mperham)
|
7
|
+
* Drop rspec in favor of test/unit, for 1.9 compat (mperham)
|
8
|
+
|
1
9
|
= 1.5.0.3 (FiveRuns fork)
|
2
10
|
|
3
11
|
* Integrated ITU-T CRC32 operation in native C extension for speed. Thanks to Justin Balthrop!
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# vim: syntax=Ruby
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rake/rdoctask'
|
4
|
-
require '
|
4
|
+
require 'rake/testtask'
|
5
5
|
|
6
6
|
task :gem do
|
7
7
|
sh "gem build memcache-client.gemspec"
|
@@ -11,14 +11,12 @@ task :install => [:gem] do
|
|
11
11
|
sh "sudo gem install memcache-client-*.gem"
|
12
12
|
end
|
13
13
|
|
14
|
-
Spec::Rake::SpecTask.new do |t|
|
15
|
-
t.ruby_opts = ['-rtest/unit']
|
16
|
-
t.spec_files = FileList['test/test_*.rb']
|
17
|
-
t.fail_on_error = true
|
18
|
-
end
|
19
|
-
|
20
14
|
Rake::RDocTask.new do |rd|
|
21
15
|
rd.main = "README.rdoc"
|
22
16
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
23
17
|
rd.rdoc_dir = 'doc'
|
24
18
|
end
|
19
|
+
|
20
|
+
Rake::TestTask.new
|
21
|
+
|
22
|
+
task :default => :test
|
data/ext/crc32/crc32.c
CHANGED
@@ -3,8 +3,18 @@
|
|
3
3
|
|
4
4
|
static VALUE t_itu_t(VALUE self, VALUE string) {
|
5
5
|
VALUE str = StringValue(string);
|
6
|
+
#ifdef RSTRING_LEN
|
7
|
+
int n = RSTRING_LEN(str);
|
8
|
+
#else
|
6
9
|
int n = RSTRING(str)->len;
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#ifdef RSTRING_PTR
|
13
|
+
char* p = RSTRING_PTR(str);
|
14
|
+
#else
|
7
15
|
char* p = RSTRING(str)->ptr;
|
16
|
+
#endif
|
17
|
+
|
8
18
|
unsigned long r = 0xFFFFFFFF;
|
9
19
|
int i, j;
|
10
20
|
|
data/lib/memcache.rb
CHANGED
@@ -18,11 +18,10 @@ class String
|
|
18
18
|
puts "Loading with slow CRC32 ITU-T implementation: #{e.message}"
|
19
19
|
|
20
20
|
def crc32_ITU_T
|
21
|
-
n = length
|
22
21
|
r = 0xFFFFFFFF
|
23
22
|
|
24
|
-
|
25
|
-
r ^=
|
23
|
+
each_byte do |i|
|
24
|
+
r ^= i
|
26
25
|
8.times do
|
27
26
|
if (r & 1) != 0 then
|
28
27
|
r = (r>>1) ^ 0xEDB88320
|
@@ -100,7 +99,7 @@ class MemCache
|
|
100
99
|
# Valid options for +opts+ are:
|
101
100
|
#
|
102
101
|
# [:namespace] Prepends this value to all keys added or retrieved.
|
103
|
-
# [:readonly] Raises an
|
102
|
+
# [:readonly] Raises an exception on cache writes when true.
|
104
103
|
# [:multithread] Wraps cache access in a Mutex for thread safety.
|
105
104
|
#
|
106
105
|
# Other options are ignored.
|
@@ -163,7 +162,7 @@ class MemCache
|
|
163
162
|
|
164
163
|
def servers=(servers)
|
165
164
|
# Create the server objects.
|
166
|
-
@servers = servers.collect do |server|
|
165
|
+
@servers = Array(servers).collect do |server|
|
167
166
|
case server
|
168
167
|
when String
|
169
168
|
host, port, weight = server.split ':', 3
|
@@ -198,7 +197,7 @@ class MemCache
|
|
198
197
|
cache_decr server, cache_key, amount
|
199
198
|
end
|
200
199
|
rescue TypeError => err
|
201
|
-
handle_error
|
200
|
+
handle_error nil, err
|
202
201
|
end
|
203
202
|
|
204
203
|
##
|
@@ -213,7 +212,7 @@ class MemCache
|
|
213
212
|
return value
|
214
213
|
end
|
215
214
|
rescue TypeError => err
|
216
|
-
handle_error
|
215
|
+
handle_error nil, err
|
217
216
|
end
|
218
217
|
|
219
218
|
##
|
@@ -249,17 +248,17 @@ class MemCache
|
|
249
248
|
|
250
249
|
results = {}
|
251
250
|
|
252
|
-
server_keys.each do |server,
|
253
|
-
|
254
|
-
values = cache_get_multi server,
|
251
|
+
server_keys.each do |server, keys_for_server|
|
252
|
+
keys_for_server = keys_for_server.join ' '
|
253
|
+
values = cache_get_multi server, keys_for_server
|
255
254
|
values.each do |key, value|
|
256
255
|
results[cache_keys[key]] = Marshal.load value
|
257
256
|
end
|
258
257
|
end
|
259
258
|
|
260
259
|
return results
|
261
|
-
rescue TypeError => err
|
262
|
-
handle_error
|
260
|
+
rescue TypeError, IndexError => err
|
261
|
+
handle_error nil, err
|
263
262
|
end
|
264
263
|
|
265
264
|
##
|
@@ -273,9 +272,9 @@ class MemCache
|
|
273
272
|
cache_incr server, cache_key, amount
|
274
273
|
end
|
275
274
|
rescue TypeError => err
|
276
|
-
handle_error
|
275
|
+
handle_error nil, err
|
277
276
|
end
|
278
|
-
|
277
|
+
|
279
278
|
##
|
280
279
|
# Add +key+ to the cache with value +value+ that expires in +expiry+
|
281
280
|
# seconds. If +raw+ is true, +value+ will not be Marshalled.
|
@@ -293,15 +292,14 @@ class MemCache
|
|
293
292
|
with_socket_management(server) do |socket|
|
294
293
|
socket.write command
|
295
294
|
result = socket.gets
|
296
|
-
|
295
|
+
raise_on_error_response! result
|
296
|
+
|
297
|
+
if result.nil?
|
297
298
|
server.close
|
298
299
|
raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
|
299
300
|
end
|
300
301
|
|
301
|
-
|
302
|
-
server.close
|
303
|
-
raise MemCacheError, $1.strip
|
304
|
-
end
|
302
|
+
result
|
305
303
|
end
|
306
304
|
end
|
307
305
|
end
|
@@ -322,21 +320,25 @@ class MemCache
|
|
322
320
|
|
323
321
|
with_socket_management(server) do |socket|
|
324
322
|
socket.write command
|
325
|
-
socket.gets
|
323
|
+
result = socket.gets
|
324
|
+
raise_on_error_response! result
|
325
|
+
result
|
326
326
|
end
|
327
327
|
end
|
328
328
|
end
|
329
|
-
|
329
|
+
|
330
330
|
##
|
331
331
|
# Removes +key+ from the cache in +expiry+ seconds.
|
332
332
|
|
333
333
|
def delete(key, expiry = 0)
|
334
334
|
raise MemCacheError, "Update of readonly cache" if @readonly
|
335
|
-
server, cache_key
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
335
|
+
with_server(key) do |server, cache_key|
|
336
|
+
with_socket_management(server) do |socket|
|
337
|
+
socket.write "delete #{cache_key} #{expiry}\r\n"
|
338
|
+
result = socket.gets
|
339
|
+
raise_on_error_response! result
|
340
|
+
result
|
341
|
+
end
|
340
342
|
end
|
341
343
|
end
|
342
344
|
|
@@ -346,15 +348,19 @@ class MemCache
|
|
346
348
|
def flush_all
|
347
349
|
raise MemCacheError, 'No active servers' unless active?
|
348
350
|
raise MemCacheError, "Update of readonly cache" if @readonly
|
351
|
+
|
349
352
|
begin
|
350
353
|
@mutex.lock if @multithread
|
351
354
|
@servers.each do |server|
|
352
355
|
with_socket_management(server) do |socket|
|
353
356
|
socket.write "flush_all\r\n"
|
354
357
|
result = socket.gets
|
355
|
-
|
358
|
+
raise_on_error_response! result
|
359
|
+
result
|
356
360
|
end
|
357
361
|
end
|
362
|
+
rescue IndexError => err
|
363
|
+
handle_error nil, err
|
358
364
|
ensure
|
359
365
|
@mutex.unlock if @multithread
|
360
366
|
end
|
@@ -407,13 +413,15 @@ class MemCache
|
|
407
413
|
|
408
414
|
@servers.each do |server|
|
409
415
|
next unless server.alive?
|
416
|
+
|
410
417
|
with_socket_management(server) do |socket|
|
411
|
-
value = nil
|
418
|
+
value = nil
|
412
419
|
socket.write "stats\r\n"
|
413
420
|
stats = {}
|
414
421
|
while line = socket.gets do
|
422
|
+
raise_on_error_response! line
|
415
423
|
break if line == "END\r\n"
|
416
|
-
if line =~
|
424
|
+
if line =~ /\ASTAT ([\w]+) ([\w\.\:]+)/ then
|
417
425
|
name, value = $1, $2
|
418
426
|
stats[name] = case name
|
419
427
|
when 'version'
|
@@ -423,7 +431,7 @@ class MemCache
|
|
423
431
|
microseconds ||= 0
|
424
432
|
Float(seconds) + (Float(microseconds) / 1_000_000)
|
425
433
|
else
|
426
|
-
if value =~
|
434
|
+
if value =~ /\A\d+\Z/ then
|
427
435
|
value.to_i
|
428
436
|
else
|
429
437
|
value
|
@@ -435,6 +443,7 @@ class MemCache
|
|
435
443
|
end
|
436
444
|
end
|
437
445
|
|
446
|
+
raise MemCacheError, "No active servers" if server_stats.empty?
|
438
447
|
server_stats
|
439
448
|
end
|
440
449
|
|
@@ -478,7 +487,7 @@ class MemCache
|
|
478
487
|
hkey = hash_for key
|
479
488
|
|
480
489
|
20.times do |try|
|
481
|
-
server = @buckets[hkey % @buckets.
|
490
|
+
server = @buckets[hkey % @buckets.compact.size]
|
482
491
|
return server if server.alive?
|
483
492
|
hkey += hash_for "#{try}#{key}"
|
484
493
|
end
|
@@ -502,6 +511,7 @@ class MemCache
|
|
502
511
|
with_socket_management(server) do |socket|
|
503
512
|
socket.write "decr #{cache_key} #{amount}\r\n"
|
504
513
|
text = socket.gets
|
514
|
+
raise_on_error_response! text
|
505
515
|
return nil if text == "NOT_FOUND\r\n"
|
506
516
|
return text.to_i
|
507
517
|
end
|
@@ -518,9 +528,10 @@ class MemCache
|
|
518
528
|
|
519
529
|
if keyline.nil? then
|
520
530
|
server.close
|
521
|
-
raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
|
531
|
+
raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
|
522
532
|
end
|
523
533
|
|
534
|
+
raise_on_error_response! keyline
|
524
535
|
return nil if keyline == "END\r\n"
|
525
536
|
|
526
537
|
unless keyline =~ /(\d+)\r/ then
|
@@ -544,8 +555,9 @@ class MemCache
|
|
544
555
|
|
545
556
|
while keyline = socket.gets do
|
546
557
|
return values if keyline == "END\r\n"
|
558
|
+
raise_on_error_response! keyline
|
547
559
|
|
548
|
-
unless keyline =~
|
560
|
+
unless keyline =~ /\AVALUE (.+) (.+) (.+)/ then
|
549
561
|
server.close
|
550
562
|
raise MemCacheError, "unexpected response #{keyline.inspect}"
|
551
563
|
end
|
@@ -568,31 +580,36 @@ class MemCache
|
|
568
580
|
with_socket_management(server) do |socket|
|
569
581
|
socket.write "incr #{cache_key} #{amount}\r\n"
|
570
582
|
text = socket.gets
|
583
|
+
raise_on_error_response! text
|
571
584
|
return nil if text == "NOT_FOUND\r\n"
|
572
585
|
return text.to_i
|
573
586
|
end
|
574
587
|
end
|
575
|
-
|
588
|
+
|
576
589
|
##
|
577
590
|
# Gets or creates a socket connected to the given server, and yields it
|
578
|
-
# to the block
|
579
|
-
#
|
580
|
-
#
|
581
|
-
#
|
591
|
+
# to the block, wrapped in a mutex synchronization if @multithread is true.
|
592
|
+
#
|
593
|
+
# If a socket error (SocketError, SystemCallError, IOError) or protocol error
|
594
|
+
# (MemCacheError) is raised by the block, closes the socket, attempts to
|
595
|
+
# connect again, and retries the block (once). If an error is again raised,
|
596
|
+
# reraises it as MemCacheError.
|
597
|
+
#
|
582
598
|
# If unable to connect to the server (or if in the reconnect wait period),
|
583
|
-
# raises MemCacheError
|
599
|
+
# raises MemCacheError. Note that the socket connect code marks a server
|
584
600
|
# dead for a timeout period, so retrying does not apply to connection attempt
|
585
|
-
# failures (but does still apply to unexpectedly lost connections etc.).
|
586
|
-
# Wraps the whole lot in mutex synchronization if @multithread is true.
|
601
|
+
# failures (but does still apply to unexpectedly lost connections etc.).
|
587
602
|
|
588
603
|
def with_socket_management(server, &block)
|
589
604
|
@mutex.lock if @multithread
|
590
605
|
retried = false
|
591
606
|
begin
|
592
607
|
socket = server.socket
|
593
|
-
|
594
|
-
#
|
608
|
+
|
609
|
+
# Raise an IndexError to show this server is out of whack. If were inside
|
610
|
+
# a with_server block, we'll catch it and attempt to restart the operation.
|
595
611
|
raise IndexError, "No connection to server (#{server.status})" if socket.nil?
|
612
|
+
|
596
613
|
block.call(socket)
|
597
614
|
rescue MemCacheError, SocketError, SystemCallError, IOError => err
|
598
615
|
handle_error(server, err) if retried || socket.nil?
|
@@ -610,7 +627,7 @@ class MemCache
|
|
610
627
|
yield server, cache_key
|
611
628
|
rescue IndexError => e
|
612
629
|
if !retried && @servers.size > 1
|
613
|
-
puts "Connection to server #{server.inspect} DIED!
|
630
|
+
puts "Connection to server #{server.inspect} DIED! Retrying operation..."
|
614
631
|
retried = true
|
615
632
|
retry
|
616
633
|
end
|
@@ -640,6 +657,12 @@ class MemCache
|
|
640
657
|
return server, cache_key
|
641
658
|
end
|
642
659
|
|
660
|
+
def raise_on_error_response!(response)
|
661
|
+
if response =~ /\A(?:CLIENT_|SERVER_)?ERROR(.*)/
|
662
|
+
raise MemCacheError, $1.strip
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
643
666
|
##
|
644
667
|
# This class represents a memcached server instance.
|
645
668
|
|
data/test/test_mem_cache.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'stringio'
|
2
3
|
require 'test/unit'
|
3
|
-
require 'rubygems'
|
4
|
-
require 'test/zentest_assertions'
|
5
4
|
|
6
5
|
$TESTING = true
|
7
6
|
|
8
|
-
require 'memcache'
|
7
|
+
require File.dirname(__FILE__) + '/../lib/memcache'
|
9
8
|
|
10
9
|
class MemCache
|
11
10
|
|
@@ -86,7 +85,9 @@ class TestMemCache < Test::Unit::TestCase
|
|
86
85
|
|
87
86
|
def test_cache_get_bad_state
|
88
87
|
server = FakeServer.new
|
89
|
-
|
88
|
+
|
89
|
+
# Write two messages to the socket to test failover
|
90
|
+
server.socket.data.write "bogus response\r\nbogus response\r\n"
|
90
91
|
server.socket.data.rewind
|
91
92
|
|
92
93
|
@cache.servers = []
|
@@ -96,12 +97,11 @@ class TestMemCache < Test::Unit::TestCase
|
|
96
97
|
@cache.cache_get(server, 'my_namespace:key')
|
97
98
|
end
|
98
99
|
|
99
|
-
|
100
|
+
assert_match /#{Regexp.quote 'unexpected response "bogus response\r\n"'}/, e.message
|
100
101
|
|
101
|
-
|
102
|
+
assert !server.alive?
|
102
103
|
|
103
|
-
|
104
|
-
server.socket.written.string
|
104
|
+
assert_match /get my_namespace:key\r\n/, server.socket.written.string
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_cache_get_miss
|
@@ -145,7 +145,9 @@ class TestMemCache < Test::Unit::TestCase
|
|
145
145
|
|
146
146
|
def test_cache_get_multi_bad_state
|
147
147
|
server = FakeServer.new
|
148
|
-
|
148
|
+
|
149
|
+
# Write two messages to the socket to test failover
|
150
|
+
server.socket.data.write "bogus response\r\nbogus response\r\n"
|
149
151
|
server.socket.data.rewind
|
150
152
|
|
151
153
|
@cache.servers = []
|
@@ -155,17 +157,22 @@ class TestMemCache < Test::Unit::TestCase
|
|
155
157
|
@cache.cache_get_multi server, 'my_namespace:key'
|
156
158
|
end
|
157
159
|
|
158
|
-
|
160
|
+
assert_match /#{Regexp.quote 'unexpected response "bogus response\r\n"'}/, e.message
|
159
161
|
|
160
|
-
|
162
|
+
assert !server.alive?
|
161
163
|
|
162
|
-
|
163
|
-
server.socket.written.string
|
164
|
+
assert_match /get my_namespace:key\r\n/, server.socket.written.string
|
164
165
|
end
|
165
166
|
|
166
167
|
def test_crc32_ITU_T
|
167
168
|
assert_equal 0, ''.crc32_ITU_T
|
168
|
-
|
169
|
+
# First value is the fast C version, last value is the pure Ruby version
|
170
|
+
assert_in [-886631737, 1260851911], 'my_namespace:key'.crc32_ITU_T
|
171
|
+
assert_in [-224284233, 870540390], 'my_name√space:key'.crc32_ITU_T
|
172
|
+
end
|
173
|
+
|
174
|
+
def assert_in(possible_values, value)
|
175
|
+
assert possible_values.include?(value), "#{possible_values.inspect} should contain #{value}"
|
169
176
|
end
|
170
177
|
|
171
178
|
def test_initialize
|
@@ -216,7 +223,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
216
223
|
assert_equal 'my_namespace', cache.namespace
|
217
224
|
assert_equal true, cache.readonly?
|
218
225
|
assert_equal false, cache.servers.empty?
|
219
|
-
|
226
|
+
assert !cache.instance_variable_get(:@buckets).empty?
|
220
227
|
end
|
221
228
|
|
222
229
|
def test_initialize_too_many_args
|
@@ -503,7 +510,9 @@ class TestMemCache < Test::Unit::TestCase
|
|
503
510
|
|
504
511
|
@cache.set 'key', 'value'
|
505
512
|
|
506
|
-
|
513
|
+
dumped = Marshal.dump('value')
|
514
|
+
expected = "set my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
515
|
+
# expected = "set my_namespace:key 0 0 9\r\n\004\b\"\nvalue\r\n"
|
507
516
|
assert_equal expected, server.socket.written.string
|
508
517
|
end
|
509
518
|
|
@@ -516,7 +525,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
516
525
|
|
517
526
|
@cache.set 'key', 'value', 5
|
518
527
|
|
519
|
-
|
528
|
+
dumped = Marshal.dump('value')
|
529
|
+
expected = "set my_namespace:key 0 5 #{dumped.length}\r\n#{dumped}\r\n"
|
520
530
|
assert_equal expected, server.socket.written.string
|
521
531
|
end
|
522
532
|
|
@@ -545,8 +555,11 @@ class TestMemCache < Test::Unit::TestCase
|
|
545
555
|
|
546
556
|
def test_set_too_big
|
547
557
|
server = FakeServer.new
|
548
|
-
|
558
|
+
|
559
|
+
# Write two messages to the socket to test failover
|
560
|
+
server.socket.data.write "SERVER_ERROR\r\nSERVER_ERROR object too large for cache\r\n"
|
549
561
|
server.socket.data.rewind
|
562
|
+
|
550
563
|
@cache.servers = []
|
551
564
|
@cache.servers << server
|
552
565
|
|
@@ -554,7 +567,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
554
567
|
@cache.set 'key', 'v'
|
555
568
|
end
|
556
569
|
|
557
|
-
|
570
|
+
assert_match /object too large for cache/, e.message
|
558
571
|
end
|
559
572
|
|
560
573
|
def test_add
|
@@ -565,8 +578,10 @@ class TestMemCache < Test::Unit::TestCase
|
|
565
578
|
@cache.servers << server
|
566
579
|
|
567
580
|
@cache.add 'key', 'value'
|
581
|
+
|
582
|
+
dumped = Marshal.dump('value')
|
568
583
|
|
569
|
-
expected = "add my_namespace:key 0 0
|
584
|
+
expected = "add my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
570
585
|
assert_equal expected, server.socket.written.string
|
571
586
|
end
|
572
587
|
|
@@ -579,7 +594,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
579
594
|
|
580
595
|
@cache.add 'key', 'value'
|
581
596
|
|
582
|
-
|
597
|
+
dumped = Marshal.dump('value')
|
598
|
+
expected = "add my_namespace:key 0 0 #{dumped.length}\r\n#{dumped}\r\n"
|
583
599
|
assert_equal expected, server.socket.written.string
|
584
600
|
end
|
585
601
|
|
@@ -592,7 +608,8 @@ class TestMemCache < Test::Unit::TestCase
|
|
592
608
|
|
593
609
|
@cache.add 'key', 'value', 5
|
594
610
|
|
595
|
-
|
611
|
+
dumped = Marshal.dump('value')
|
612
|
+
expected = "add my_namespace:key 0 5 #{dumped.length}\r\n#{dumped}\r\n"
|
596
613
|
assert_equal expected, server.socket.written.string
|
597
614
|
end
|
598
615
|
|
@@ -655,11 +672,12 @@ class TestMemCache < Test::Unit::TestCase
|
|
655
672
|
|
656
673
|
def test_flush_all_failure
|
657
674
|
socket = FakeSocket.new
|
658
|
-
|
675
|
+
|
676
|
+
# Write two messages to the socket to test failover
|
677
|
+
socket.data.write "ERROR\r\nERROR\r\n"
|
659
678
|
socket.data.rewind
|
679
|
+
|
660
680
|
server = FakeServer.new socket
|
661
|
-
def server.host() "localhost"; end
|
662
|
-
def server.port() 11211; end
|
663
681
|
|
664
682
|
@cache.servers = []
|
665
683
|
@cache.servers << server
|
@@ -668,7 +686,7 @@ class TestMemCache < Test::Unit::TestCase
|
|
668
686
|
@cache.flush_all
|
669
687
|
end
|
670
688
|
|
671
|
-
|
689
|
+
assert_match /flush_all\r\n/, socket.written.string
|
672
690
|
end
|
673
691
|
|
674
692
|
def test_stats
|
@@ -697,24 +715,44 @@ class TestMemCache < Test::Unit::TestCase
|
|
697
715
|
cache = MemCache.new :multithread => true,
|
698
716
|
:namespace => 'my_namespace',
|
699
717
|
:readonly => false
|
700
|
-
|
701
|
-
|
718
|
+
|
719
|
+
server = FakeServer.new
|
720
|
+
server.socket.data.write "STORED\r\n"
|
721
|
+
server.socket.data.rewind
|
722
|
+
|
723
|
+
cache.servers = []
|
724
|
+
cache.servers << server
|
725
|
+
|
726
|
+
assert cache.multithread
|
702
727
|
|
703
728
|
assert_nothing_raised do
|
704
729
|
cache.set "test", "test value"
|
705
730
|
end
|
731
|
+
|
732
|
+
# TODO Fails in 1.9
|
733
|
+
assert_match /set my_namespace:test.*\r\n.*test value.*\r\n/, server.socket.written.string
|
706
734
|
end
|
707
735
|
|
708
736
|
def test_basic_unthreaded_operations_should_work
|
709
737
|
cache = MemCache.new :multithread => false,
|
710
738
|
:namespace => 'my_namespace',
|
711
739
|
:readonly => false
|
712
|
-
|
713
|
-
|
740
|
+
|
741
|
+
server = FakeServer.new
|
742
|
+
server.socket.data.write "STORED\r\n"
|
743
|
+
server.socket.data.rewind
|
744
|
+
|
745
|
+
cache.servers = []
|
746
|
+
cache.servers << server
|
747
|
+
|
748
|
+
assert !cache.multithread
|
714
749
|
|
715
750
|
assert_nothing_raised do
|
716
751
|
cache.set "test", "test value"
|
717
752
|
end
|
753
|
+
|
754
|
+
# TODO Fails in 1.9
|
755
|
+
assert_match /set my_namespace:test.*\r\n.*test value\r\n/, server.socket.written.string
|
718
756
|
end
|
719
757
|
|
720
758
|
def util_setup_fake_server
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiveruns-memcache-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.0.
|
4
|
+
version: 1.5.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Hodel
|
@@ -11,12 +11,12 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2008-
|
14
|
+
date: 2008-10-27 00:00:00 -07:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
18
18
|
description: A Ruby-based memcached client library
|
19
|
-
email:
|
19
|
+
email: mperham@gmail.com
|
20
20
|
executables: []
|
21
21
|
|
22
22
|
extensions:
|