fiveruns-memcache-client 1.5.0.1 → 1.5.0.3
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 +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
|