fiveruns-memcache-client 1.5.0.1 → 1.5.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -0
- data/README.txt +9 -9
- data/ext/crc32/crc32.c +28 -0
- data/ext/crc32/extconf.rb +5 -0
- data/lib/memcache.rb +166 -188
- data/test/test_mem_cache.rb +1 -1
- metadata +6 -5
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
= 1.5.0.3 (FiveRuns fork)
|
2
|
+
|
3
|
+
* Integrated ITU-T CRC32 operation in native C extension for speed. Thanks to Justin Balthrop!
|
4
|
+
|
5
|
+
= 1.5.0.2 (FiveRuns fork)
|
6
|
+
|
7
|
+
* Add support for seamless failover between servers. If one server connection dies,
|
8
|
+
the client will retry the operation on another server before giving up.
|
9
|
+
|
10
|
+
* Merge Will Bryant's socket retry patch.
|
11
|
+
http://willbryant.net/software/2007/12/21/ruby-memcache-client-reconnect-and-retry
|
12
|
+
|
1
13
|
= 1.5.0.1 (FiveRuns fork)
|
2
14
|
|
3
15
|
* Fix set not handling client disconnects.
|
data/README.txt
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
= memcache-client
|
2
2
|
|
3
|
+
This is the FiveRuns fork of seattle.rb's memcache-client 1.5.0. We've fixed several bugs
|
4
|
+
which are in that version.
|
5
|
+
|
3
6
|
Rubyforge Project:
|
4
7
|
|
5
8
|
http://rubyforge.org/projects/seattlerb
|
6
9
|
|
7
|
-
File bugs:
|
8
|
-
|
9
|
-
http://rubyforge.org/tracker/?func=add&group_id=1513&atid=5921
|
10
|
-
|
11
10
|
Documentation:
|
12
11
|
|
13
12
|
http://seattlerb.org/memcache-client
|
14
13
|
|
15
|
-
== About
|
16
|
-
|
17
|
-
memcache-client is a client for Danga Interactive's memcached.
|
18
|
-
|
19
14
|
== Installing memcache-client
|
20
15
|
|
21
16
|
Just install the gem:
|
22
17
|
|
23
|
-
$ sudo gem install memcache-client
|
18
|
+
$ sudo gem install fiveruns-memcache-client --source http://gems.github.com
|
24
19
|
|
25
20
|
== Using memcache-client
|
26
21
|
|
@@ -52,3 +47,8 @@ use with Rails. To use it be sure to assign your memcache connection to
|
|
52
47
|
CACHE. Cache returns nil on all memcache errors so you don't have to rescue
|
53
48
|
the errors yourself. It has #get, #put and #delete module functions.
|
54
49
|
|
50
|
+
=== Improving Performance ===
|
51
|
+
|
52
|
+
Performing the CRC-32 ITU-T step to determine which server to use for a given key
|
53
|
+
is VERY slow in Ruby. RubyGems should compile a native library for performing this
|
54
|
+
operation when the gem is installed.
|
data/ext/crc32/crc32.c
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "stdio.h"
|
3
|
+
|
4
|
+
static VALUE t_itu_t(VALUE self, VALUE string) {
|
5
|
+
VALUE str = StringValue(string);
|
6
|
+
int n = RSTRING(str)->len;
|
7
|
+
char* p = RSTRING(str)->ptr;
|
8
|
+
unsigned long r = 0xFFFFFFFF;
|
9
|
+
int i, j;
|
10
|
+
|
11
|
+
for (i = 0; i < n; i++) {
|
12
|
+
r = r ^ p[i];
|
13
|
+
for (j = 0; j < 8; j++) {
|
14
|
+
if ( (r & 1) != 0 ) {
|
15
|
+
r = (r >> 1) ^ 0xEDB88320;
|
16
|
+
} else {
|
17
|
+
r = r >> 1;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
return INT2FIX(r ^ 0xFFFFFFFF);
|
22
|
+
}
|
23
|
+
|
24
|
+
VALUE cCRC32;
|
25
|
+
void Init_crc32() {
|
26
|
+
cCRC32 = rb_define_module("CRC32");
|
27
|
+
rb_define_module_function(cCRC32, "itu_t", t_itu_t, 1);
|
28
|
+
}
|
data/lib/memcache.rb
CHANGED
@@ -9,25 +9,33 @@ class String
|
|
9
9
|
|
10
10
|
##
|
11
11
|
# Uses the ITU-T polynomial in the CRC32 algorithm.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
begin
|
13
|
+
require 'crc32'
|
14
|
+
def crc32_ITU_T
|
15
|
+
CRC32.itu_t(self)
|
16
|
+
end
|
17
|
+
rescue LoadError => e
|
18
|
+
puts "Loading with slow CRC32 ITU-T implementation: #{e.message}"
|
19
|
+
|
20
|
+
def crc32_ITU_T
|
21
|
+
n = length
|
22
|
+
r = 0xFFFFFFFF
|
23
|
+
|
24
|
+
n.times do |i|
|
25
|
+
r ^= self[i]
|
26
|
+
8.times do
|
27
|
+
if (r & 1) != 0 then
|
28
|
+
r = (r>>1) ^ 0xEDB88320
|
29
|
+
else
|
30
|
+
r >>= 1
|
31
|
+
end
|
24
32
|
end
|
25
33
|
end
|
26
|
-
end
|
27
34
|
|
28
|
-
|
35
|
+
r ^ 0xFFFFFFFF
|
36
|
+
end
|
29
37
|
end
|
30
|
-
|
38
|
+
|
31
39
|
end
|
32
40
|
|
33
41
|
##
|
@@ -180,19 +188,16 @@ class MemCache
|
|
180
188
|
end
|
181
189
|
|
182
190
|
##
|
183
|
-
#
|
191
|
+
# Decrements the value for +key+ by +amount+ and returns the new value.
|
184
192
|
# +key+ must already exist. If +key+ is not an integer, it is assumed to be
|
185
193
|
# 0. +key+ can not be decremented below 0.
|
186
194
|
|
187
195
|
def decr(key, amount = 1)
|
188
|
-
|
189
|
-
|
190
|
-
if @multithread then
|
191
|
-
threadsafe_cache_decr server, cache_key, amount
|
192
|
-
else
|
196
|
+
raise MemCacheError, "Update of readonly cache" if @readonly
|
197
|
+
with_server(key) do |server, cache_key|
|
193
198
|
cache_decr server, cache_key, amount
|
194
199
|
end
|
195
|
-
rescue TypeError
|
200
|
+
rescue TypeError => err
|
196
201
|
handle_error server, err
|
197
202
|
end
|
198
203
|
|
@@ -201,20 +206,13 @@ class MemCache
|
|
201
206
|
# unmarshalled.
|
202
207
|
|
203
208
|
def get(key, raw = false)
|
204
|
-
server, cache_key
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
return nil if value.nil?
|
213
|
-
|
214
|
-
value = Marshal.load value unless raw
|
215
|
-
|
216
|
-
return value
|
217
|
-
rescue TypeError, SocketError, SystemCallError, IOError => err
|
209
|
+
with_server(key) do |server, cache_key|
|
210
|
+
value = cache_get server, cache_key
|
211
|
+
return nil if value.nil?
|
212
|
+
value = Marshal.load value unless raw
|
213
|
+
return value
|
214
|
+
end
|
215
|
+
rescue TypeError => err
|
218
216
|
handle_error server, err
|
219
217
|
end
|
220
218
|
|
@@ -253,38 +251,31 @@ class MemCache
|
|
253
251
|
|
254
252
|
server_keys.each do |server, keys|
|
255
253
|
keys = keys.join ' '
|
256
|
-
values =
|
257
|
-
threadsafe_cache_get_multi server, keys
|
258
|
-
else
|
259
|
-
cache_get_multi server, keys
|
260
|
-
end
|
254
|
+
values = cache_get_multi server, keys
|
261
255
|
values.each do |key, value|
|
262
256
|
results[cache_keys[key]] = Marshal.load value
|
263
257
|
end
|
264
258
|
end
|
265
259
|
|
266
260
|
return results
|
267
|
-
rescue TypeError
|
261
|
+
rescue TypeError => err
|
268
262
|
handle_error server, err
|
269
263
|
end
|
270
264
|
|
271
265
|
##
|
272
|
-
# Increments the value for +key+ by +amount+ and
|
266
|
+
# Increments the value for +key+ by +amount+ and returns the new value.
|
273
267
|
# +key+ must already exist. If +key+ is not an integer, it is assumed to be
|
274
268
|
# 0.
|
275
269
|
|
276
270
|
def incr(key, amount = 1)
|
277
|
-
|
278
|
-
|
279
|
-
if @multithread then
|
280
|
-
threadsafe_cache_incr server, cache_key, amount
|
281
|
-
else
|
271
|
+
raise MemCacheError, "Update of readonly cache" if @readonly
|
272
|
+
with_server(key) do |server, cache_key|
|
282
273
|
cache_incr server, cache_key, amount
|
283
274
|
end
|
284
|
-
rescue TypeError
|
275
|
+
rescue TypeError => err
|
285
276
|
handle_error server, err
|
286
277
|
end
|
287
|
-
|
278
|
+
|
288
279
|
##
|
289
280
|
# Add +key+ to the cache with value +value+ that expires in +expiry+
|
290
281
|
# seconds. If +raw+ is true, +value+ will not be Marshalled.
|
@@ -294,30 +285,24 @@ class MemCache
|
|
294
285
|
|
295
286
|
def set(key, value, expiry = 0, raw = false)
|
296
287
|
raise MemCacheError, "Update of readonly cache" if @readonly
|
297
|
-
server, cache_key
|
298
|
-
socket = server.socket
|
288
|
+
with_server(key) do |server, cache_key|
|
299
289
|
|
300
|
-
|
301
|
-
|
290
|
+
value = Marshal.dump value unless raw
|
291
|
+
command = "set #{cache_key} 0 #{expiry} #{value.to_s.size}\r\n#{value}\r\n"
|
302
292
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
end
|
293
|
+
with_socket_management(server) do |socket|
|
294
|
+
socket.write command
|
295
|
+
result = socket.gets
|
296
|
+
if result.nil?
|
297
|
+
server.close
|
298
|
+
raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
|
299
|
+
end
|
311
300
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
server.close
|
318
|
-
raise MemCacheError, err.message
|
319
|
-
ensure
|
320
|
-
@mutex.unlock if @multithread
|
301
|
+
if result =~ /^SERVER_ERROR (.*)/
|
302
|
+
server.close
|
303
|
+
raise MemCacheError, $1.strip
|
304
|
+
end
|
305
|
+
end
|
321
306
|
end
|
322
307
|
end
|
323
308
|
|
@@ -331,46 +316,28 @@ class MemCache
|
|
331
316
|
|
332
317
|
def add(key, value, expiry = 0, raw = false)
|
333
318
|
raise MemCacheError, "Update of readonly cache" if @readonly
|
334
|
-
server, cache_key
|
335
|
-
|
336
|
-
|
337
|
-
value = Marshal.dump value unless raw
|
338
|
-
command = "add #{cache_key} 0 #{expiry} #{value.size}\r\n#{value}\r\n"
|
319
|
+
with_server(key) do |server, cache_key|
|
320
|
+
value = Marshal.dump value unless raw
|
321
|
+
command = "add #{cache_key} 0 #{expiry} #{value.size}\r\n#{value}\r\n"
|
339
322
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
rescue SocketError, SystemCallError, IOError => err
|
345
|
-
server.close
|
346
|
-
raise MemCacheError, err.message
|
347
|
-
ensure
|
348
|
-
@mutex.unlock if @multithread
|
323
|
+
with_socket_management(server) do |socket|
|
324
|
+
socket.write command
|
325
|
+
socket.gets
|
326
|
+
end
|
349
327
|
end
|
350
328
|
end
|
351
|
-
|
329
|
+
|
352
330
|
##
|
353
331
|
# Removes +key+ from the cache in +expiry+ seconds.
|
354
332
|
|
355
333
|
def delete(key, expiry = 0)
|
356
|
-
|
357
|
-
|
358
|
-
raise MemCacheError, "No active servers" unless active?
|
359
|
-
cache_key = make_cache_key key
|
360
|
-
server = get_server_for_key cache_key
|
361
|
-
|
362
|
-
sock = server.socket
|
363
|
-
raise MemCacheError, "No connection to server" if sock.nil?
|
334
|
+
raise MemCacheError, "Update of readonly cache" if @readonly
|
335
|
+
server, cache_key = request_setup key
|
364
336
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
rescue SocketError, SystemCallError, IOError => err
|
369
|
-
server.close
|
370
|
-
raise MemCacheError, err.message
|
337
|
+
with_socket_management(server) do |socket|
|
338
|
+
socket.write "delete #{cache_key} #{expiry}\r\n"
|
339
|
+
socket.gets
|
371
340
|
end
|
372
|
-
ensure
|
373
|
-
@mutex.unlock if @multithread
|
374
341
|
end
|
375
342
|
|
376
343
|
##
|
@@ -382,15 +349,10 @@ class MemCache
|
|
382
349
|
begin
|
383
350
|
@mutex.lock if @multithread
|
384
351
|
@servers.each do |server|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
sock.write "flush_all\r\n"
|
389
|
-
result = sock.gets
|
352
|
+
with_socket_management(server) do |socket|
|
353
|
+
socket.write "flush_all\r\n"
|
354
|
+
result = socket.gets
|
390
355
|
raise MemCacheError, $2.strip if result =~ /^(SERVER_)?ERROR(.*)/
|
391
|
-
rescue SocketError, SystemCallError, IOError => err
|
392
|
-
server.close
|
393
|
-
raise MemCacheError, err.message
|
394
356
|
end
|
395
357
|
end
|
396
358
|
ensure
|
@@ -444,14 +406,12 @@ class MemCache
|
|
444
406
|
server_stats = {}
|
445
407
|
|
446
408
|
@servers.each do |server|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
begin
|
452
|
-
sock.write "stats\r\n"
|
409
|
+
next unless server.alive?
|
410
|
+
with_socket_management(server) do |socket|
|
411
|
+
value = nil # TODO: why is this line here?
|
412
|
+
socket.write "stats\r\n"
|
453
413
|
stats = {}
|
454
|
-
while line =
|
414
|
+
while line = socket.gets do
|
455
415
|
break if line == "END\r\n"
|
456
416
|
if line =~ /^STAT ([\w]+) ([\w\.\:]+)/ then
|
457
417
|
name, value = $1, $2
|
@@ -472,9 +432,6 @@ class MemCache
|
|
472
432
|
end
|
473
433
|
end
|
474
434
|
server_stats["#{server.host}:#{server.port}"] = stats
|
475
|
-
rescue SocketError, SystemCallError, IOError => err
|
476
|
-
server.close
|
477
|
-
raise MemCacheError, err.message
|
478
435
|
end
|
479
436
|
end
|
480
437
|
|
@@ -542,11 +499,12 @@ class MemCache
|
|
542
499
|
# found.
|
543
500
|
|
544
501
|
def cache_decr(server, cache_key, amount)
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
502
|
+
with_socket_management(server) do |socket|
|
503
|
+
socket.write "decr #{cache_key} #{amount}\r\n"
|
504
|
+
text = socket.gets
|
505
|
+
return nil if text == "NOT_FOUND\r\n"
|
506
|
+
return text.to_i
|
507
|
+
end
|
550
508
|
end
|
551
509
|
|
552
510
|
##
|
@@ -554,50 +512,52 @@ class MemCache
|
|
554
512
|
# miss.
|
555
513
|
|
556
514
|
def cache_get(server, cache_key)
|
557
|
-
|
558
|
-
|
559
|
-
|
515
|
+
with_socket_management(server) do |socket|
|
516
|
+
socket.write "get #{cache_key}\r\n"
|
517
|
+
keyline = socket.gets # "VALUE <key> <flags> <bytes>\r\n"
|
560
518
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
519
|
+
if keyline.nil? then
|
520
|
+
server.close
|
521
|
+
raise MemCacheError, "lost connection to #{server.host}:#{server.port}" # TODO: retry here too
|
522
|
+
end
|
565
523
|
|
566
|
-
|
524
|
+
return nil if keyline == "END\r\n"
|
567
525
|
|
568
|
-
|
569
|
-
|
570
|
-
|
526
|
+
unless keyline =~ /(\d+)\r/ then
|
527
|
+
server.close
|
528
|
+
raise MemCacheError, "unexpected response #{keyline.inspect}"
|
529
|
+
end
|
530
|
+
value = socket.read $1.to_i
|
531
|
+
socket.read 2 # "\r\n"
|
532
|
+
socket.gets # "END\r\n"
|
533
|
+
return value
|
571
534
|
end
|
572
|
-
value = socket.read $1.to_i
|
573
|
-
socket.read 2 # "\r\n"
|
574
|
-
socket.gets # "END\r\n"
|
575
|
-
return value
|
576
535
|
end
|
577
536
|
|
578
537
|
##
|
579
538
|
# Fetches +cache_keys+ from +server+ using a multi-get.
|
580
539
|
|
581
540
|
def cache_get_multi(server, cache_keys)
|
582
|
-
|
583
|
-
|
584
|
-
|
541
|
+
with_socket_management(server) do |socket|
|
542
|
+
values = {}
|
543
|
+
socket.write "get #{cache_keys}\r\n"
|
585
544
|
|
586
|
-
|
587
|
-
|
545
|
+
while keyline = socket.gets do
|
546
|
+
return values if keyline == "END\r\n"
|
588
547
|
|
589
|
-
|
590
|
-
|
591
|
-
|
548
|
+
unless keyline =~ /^VALUE (.+) (.+) (.+)/ then
|
549
|
+
server.close
|
550
|
+
raise MemCacheError, "unexpected response #{keyline.inspect}"
|
551
|
+
end
|
552
|
+
|
553
|
+
key, data_length = $1, $3
|
554
|
+
values[$1] = socket.read data_length.to_i
|
555
|
+
socket.read(2) # "\r\n"
|
592
556
|
end
|
593
557
|
|
594
|
-
|
595
|
-
|
596
|
-
socket.read(2) # "\r\n"
|
558
|
+
server.close
|
559
|
+
raise MemCacheError, "lost connection to #{server.host}:#{server.port}" # TODO: retry here too
|
597
560
|
end
|
598
|
-
|
599
|
-
server.close
|
600
|
-
raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
|
601
561
|
end
|
602
562
|
|
603
563
|
##
|
@@ -605,17 +565,64 @@ class MemCache
|
|
605
565
|
# found.
|
606
566
|
|
607
567
|
def cache_incr(server, cache_key, amount)
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
568
|
+
with_socket_management(server) do |socket|
|
569
|
+
socket.write "incr #{cache_key} #{amount}\r\n"
|
570
|
+
text = socket.gets
|
571
|
+
return nil if text == "NOT_FOUND\r\n"
|
572
|
+
return text.to_i
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
##
|
577
|
+
# Gets or creates a socket connected to the given server, and yields it
|
578
|
+
# to the block. If a socket error (SocketError, SystemCallError, IOError)
|
579
|
+
# or protocol error (MemCacheError) is raised by the block, closes the
|
580
|
+
# socket, attempts to connect again, and retries the block (once). If
|
581
|
+
# an error is again raised, reraises it as MemCacheError.
|
582
|
+
# If unable to connect to the server (or if in the reconnect wait period),
|
583
|
+
# raises MemCacheError - note that the socket connect code marks a server
|
584
|
+
# 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.
|
587
|
+
|
588
|
+
def with_socket_management(server, &block)
|
589
|
+
@mutex.lock if @multithread
|
590
|
+
retried = false
|
591
|
+
begin
|
592
|
+
socket = server.socket
|
593
|
+
# Raise an IndexError to show this server is out of whack.
|
594
|
+
# We'll catch it in higher-level code and attempt to restart the operation.
|
595
|
+
raise IndexError, "No connection to server (#{server.status})" if socket.nil?
|
596
|
+
block.call(socket)
|
597
|
+
rescue MemCacheError, SocketError, SystemCallError, IOError => err
|
598
|
+
handle_error(server, err) if retried || socket.nil?
|
599
|
+
retried = true
|
600
|
+
retry
|
601
|
+
end
|
602
|
+
ensure
|
603
|
+
@mutex.unlock if @multithread
|
604
|
+
end
|
605
|
+
|
606
|
+
def with_server(key)
|
607
|
+
retried = false
|
608
|
+
begin
|
609
|
+
server, cache_key = request_setup(key)
|
610
|
+
yield server, cache_key
|
611
|
+
rescue IndexError => e
|
612
|
+
if !retried && @servers.size > 1
|
613
|
+
puts "Connection to server #{server.inspect} DIED! Retrying operation..."
|
614
|
+
retried = true
|
615
|
+
retry
|
616
|
+
end
|
617
|
+
handle_error(nil, e)
|
618
|
+
end
|
613
619
|
end
|
614
620
|
|
615
621
|
##
|
616
622
|
# Handles +error+ from +server+.
|
617
623
|
|
618
624
|
def handle_error(server, error)
|
625
|
+
raise error if error.is_a?(MemCacheError)
|
619
626
|
server.close if server
|
620
627
|
new_error = MemCacheError.new error.message
|
621
628
|
new_error.set_backtrace error.backtrace
|
@@ -630,38 +637,9 @@ class MemCache
|
|
630
637
|
raise MemCacheError, 'No active servers' unless active?
|
631
638
|
cache_key = make_cache_key key
|
632
639
|
server = get_server_for_key cache_key
|
633
|
-
raise MemCacheError, 'No connection to server' if server.socket.nil?
|
634
640
|
return server, cache_key
|
635
641
|
end
|
636
642
|
|
637
|
-
def threadsafe_cache_decr(server, cache_key, amount) # :nodoc:
|
638
|
-
@mutex.lock
|
639
|
-
cache_decr server, cache_key, amount
|
640
|
-
ensure
|
641
|
-
@mutex.unlock
|
642
|
-
end
|
643
|
-
|
644
|
-
def threadsafe_cache_get(server, cache_key) # :nodoc:
|
645
|
-
@mutex.lock
|
646
|
-
cache_get server, cache_key
|
647
|
-
ensure
|
648
|
-
@mutex.unlock
|
649
|
-
end
|
650
|
-
|
651
|
-
def threadsafe_cache_get_multi(socket, cache_keys) # :nodoc:
|
652
|
-
@mutex.lock
|
653
|
-
cache_get_multi socket, cache_keys
|
654
|
-
ensure
|
655
|
-
@mutex.unlock
|
656
|
-
end
|
657
|
-
|
658
|
-
def threadsafe_cache_incr(server, cache_key, amount) # :nodoc:
|
659
|
-
@mutex.lock
|
660
|
-
cache_incr server, cache_key, amount
|
661
|
-
ensure
|
662
|
-
@mutex.unlock
|
663
|
-
end
|
664
|
-
|
665
643
|
##
|
666
644
|
# This class represents a memcached server instance.
|
667
645
|
|
data/test/test_mem_cache.rb
CHANGED
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Hodel
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2008-
|
14
|
+
date: 2008-07-06 00:00:00 -07:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
@@ -19,8 +19,8 @@ description: A Ruby-based memcached client library
|
|
19
19
|
email: mike@fiveruns.com
|
20
20
|
executables: []
|
21
21
|
|
22
|
-
extensions:
|
23
|
-
|
22
|
+
extensions:
|
23
|
+
- ext/crc32/extconf.rb
|
24
24
|
extra_rdoc_files: []
|
25
25
|
|
26
26
|
files:
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- Rakefile
|
31
31
|
- lib/memcache.rb
|
32
32
|
- lib/memcache_util.rb
|
33
|
+
- ext/crc32/crc32.c
|
33
34
|
has_rdoc: false
|
34
35
|
homepage: http://github.com/fiveruns/memcache-client
|
35
36
|
post_install_message:
|
@@ -52,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
53
|
requirements: []
|
53
54
|
|
54
55
|
rubyforge_project:
|
55
|
-
rubygems_version: 1.0
|
56
|
+
rubygems_version: 1.2.0
|
56
57
|
signing_key:
|
57
58
|
specification_version: 2
|
58
59
|
summary: A Ruby-based memcached client library
|