memcache-client 1.7.5 → 1.7.6
Sign up to get free protection for your applications and to get access to all the features.
- data/FAQ.rdoc +2 -2
- data/History.rdoc +9 -0
- data/Rakefile +16 -14
- data/VERSION.yml +4 -0
- data/lib/memcache.rb +55 -6
- data/lib/memcache_util.rb +105 -0
- data/performance.txt +143 -0
- data/test/test_benchmark.rb +134 -0
- data/test/test_mem_cache.rb +19 -0
- metadata +16 -9
data/FAQ.rdoc
CHANGED
@@ -27,5 +27,5 @@ You can increase the timeout or disable them completely with the following confi
|
|
27
27
|
|
28
28
|
The latest version of memcached-client is anywhere from 33% to 100% slower than memcached in various benchmarks. Keep in mind this means that 10,000 get requests take 1.8 sec instead of 1.2 seconds.
|
29
29
|
In practice, memcache-client is unlikely to be a bottleneck in your system but there is always going
|
30
|
-
to be an overhead to pure Ruby.
|
31
|
-
|
30
|
+
to be an overhead to pure Ruby. memcache-client does have the advantage of built-in integration into
|
31
|
+
Rails and should work on non-MRI platforms: JRuby, MacRuby, etc.
|
data/History.rdoc
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
= 1.7.6 (2009-11-03)
|
2
|
+
|
3
|
+
* Reworked socket timeout code due to several customer complaints about timeouts not
|
4
|
+
working 100% of the time since 1.7.3.
|
5
|
+
* Add option to configure the namespace separator string, for interop with Perl
|
6
|
+
which does not use a separator character:
|
7
|
+
MemCache.new(servers, :namespace_separator => '')
|
8
|
+
* Move to jeweler and gemcutter for RubyGem support.
|
9
|
+
|
1
10
|
= 1.7.5 (2009-09-09)
|
2
11
|
|
3
12
|
* Fix ruby warnings (josh)
|
data/Rakefile
CHANGED
@@ -3,22 +3,24 @@ require 'rubygems'
|
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
require 'rake/testtask'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = "memcache-client"
|
10
|
+
s.summary = s.description = "A Ruby library for accessing memcached."
|
11
|
+
s.email = "mperham@gmail.com"
|
12
|
+
s.homepage = "http://github.com/mperham/memcache-client"
|
13
|
+
s.authors = ['Eric Hodel', 'Robert Cottrell', 'Mike Perham']
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.files = FileList["[A-Z]*", "{lib,test}/**/*", 'performance.txt']
|
16
|
+
s.test_files = FileList["test/test_*.rb"]
|
17
|
+
s.rubyforge_project = 'seattlerb'
|
18
|
+
end
|
19
|
+
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install jeweler"
|
8
22
|
end
|
9
23
|
|
10
|
-
task :install => [:gem] do
|
11
|
-
sh "sudo gem install memcache-client-*.gem"
|
12
|
-
end
|
13
|
-
|
14
|
-
task :clean do
|
15
|
-
sh "rm -f memcache-client-*.gem"
|
16
|
-
end
|
17
|
-
|
18
|
-
task :publish => [:clean, :gem, :install] do
|
19
|
-
require 'lib/memcache'
|
20
|
-
sh "rubyforge add_release seattlerb memcache-client #{MemCache::VERSION} memcache-client-#{MemCache::VERSION}.gem"
|
21
|
-
end
|
22
24
|
|
23
25
|
Rake::RDocTask.new do |rd|
|
24
26
|
rd.main = "README.rdoc"
|
data/VERSION.yml
ADDED
data/lib/memcache.rb
CHANGED
@@ -6,6 +6,26 @@ require 'zlib'
|
|
6
6
|
require 'digest/sha1'
|
7
7
|
require 'net/protocol'
|
8
8
|
|
9
|
+
begin
|
10
|
+
# Try to use the SystemTimer gem instead of Ruby's timeout library
|
11
|
+
# when running on something that looks like Ruby 1.8.x. See:
|
12
|
+
# http://ph7spot.com/articles/system_timer
|
13
|
+
# We don't want to bother trying to load SystemTimer on jruby and
|
14
|
+
# ruby 1.9+
|
15
|
+
if defined?(JRUBY_VERSION) || (RUBY_VERSION >= '1.9')
|
16
|
+
require 'timeout'
|
17
|
+
MemCacheTimer = Timeout
|
18
|
+
else
|
19
|
+
require 'system_timer'
|
20
|
+
MemCacheTimer = SystemTimer
|
21
|
+
end
|
22
|
+
rescue LoadError => e
|
23
|
+
puts "[memcache-client] Could not load SystemTimer gem, falling back to Ruby's slower/unsafe timeout library: #{e.message}"
|
24
|
+
require 'timeout'
|
25
|
+
MemCacheTimer = Timeout
|
26
|
+
end
|
27
|
+
|
28
|
+
|
9
29
|
##
|
10
30
|
# A Ruby client library for memcached.
|
11
31
|
#
|
@@ -15,7 +35,10 @@ class MemCache
|
|
15
35
|
##
|
16
36
|
# The version of MemCache you are using.
|
17
37
|
|
18
|
-
VERSION =
|
38
|
+
VERSION = begin
|
39
|
+
config = YAML.load(File.read(File.dirname(__FILE__) + '/../VERSION.yml'))
|
40
|
+
"#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
41
|
+
end
|
19
42
|
|
20
43
|
##
|
21
44
|
# Default options for the cache object.
|
@@ -29,7 +52,8 @@ class MemCache
|
|
29
52
|
:logger => nil,
|
30
53
|
:no_reply => false,
|
31
54
|
:check_size => true,
|
32
|
-
:autofix_keys => false
|
55
|
+
:autofix_keys => false,
|
56
|
+
:namespace_separator => ':',
|
33
57
|
}
|
34
58
|
|
35
59
|
##
|
@@ -146,6 +170,7 @@ class MemCache
|
|
146
170
|
@logger = opts[:logger]
|
147
171
|
@no_reply = opts[:no_reply]
|
148
172
|
@check_size = opts[:check_size]
|
173
|
+
@namespace_separator = opts[:namespace_separator]
|
149
174
|
@mutex = Mutex.new if @multithread
|
150
175
|
|
151
176
|
logger.info { "memcache-client #{VERSION} #{Array(servers).inspect}" } if logger
|
@@ -648,7 +673,7 @@ class MemCache
|
|
648
673
|
if namespace.nil? then
|
649
674
|
key
|
650
675
|
else
|
651
|
-
"#{@namespace}
|
676
|
+
"#{@namespace}#{@namespace_separator}#{key}"
|
652
677
|
end
|
653
678
|
end
|
654
679
|
|
@@ -866,7 +891,7 @@ class MemCache
|
|
866
891
|
|
867
892
|
def handle_error(server, error)
|
868
893
|
raise error if error.is_a?(MemCacheError)
|
869
|
-
server.close if server
|
894
|
+
server.close if server && server.status == "CONNECTED"
|
870
895
|
new_error = MemCacheError.new error.message
|
871
896
|
new_error.set_backtrace error.backtrace
|
872
897
|
raise new_error
|
@@ -1016,7 +1041,7 @@ class MemCache
|
|
1016
1041
|
@sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
1017
1042
|
@retry = nil
|
1018
1043
|
@status = 'CONNECTED'
|
1019
|
-
rescue SocketError, SystemCallError, IOError => err
|
1044
|
+
rescue SocketError, SystemCallError, IOError, Timeout::Error => err
|
1020
1045
|
logger.warn { "Unable to open socket: #{err.class.name}, #{err.message}" } if logger
|
1021
1046
|
mark_dead err
|
1022
1047
|
end
|
@@ -1025,8 +1050,32 @@ class MemCache
|
|
1025
1050
|
end
|
1026
1051
|
|
1027
1052
|
def connect_to(host, port, timeout=nil)
|
1028
|
-
|
1053
|
+
sock = nil
|
1054
|
+
if timeout
|
1055
|
+
MemCacheTimer.timeout(timeout) do
|
1056
|
+
sock = TCPSocket.new(host, port)
|
1057
|
+
end
|
1058
|
+
else
|
1059
|
+
sock = TCPSocket.new(host, port)
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
io = MemCache::BufferedIO.new(sock)
|
1029
1063
|
io.read_timeout = timeout
|
1064
|
+
# Getting reports from several customers, including 37signals,
|
1065
|
+
# that the non-blocking timeouts in 1.7.5 don't seem to be reliable.
|
1066
|
+
# It can't hurt to set the underlying socket timeout also, if possible.
|
1067
|
+
if timeout
|
1068
|
+
secs = Integer(timeout)
|
1069
|
+
usecs = Integer((timeout - secs) * 1_000_000)
|
1070
|
+
optval = [secs, usecs].pack("l_2")
|
1071
|
+
begin
|
1072
|
+
io.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
1073
|
+
io.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
1074
|
+
rescue Exception => ex
|
1075
|
+
# Solaris, for one, does not like/support socket timeouts.
|
1076
|
+
@logger.info "[memcache-client] Unable to use raw socket timeouts: #{ex.class.name}: #{ex.message}" if @logger
|
1077
|
+
end
|
1078
|
+
end
|
1030
1079
|
io
|
1031
1080
|
end
|
1032
1081
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
##
|
2
|
+
# A utility wrapper around the MemCache client to simplify cache access. All
|
3
|
+
# methods silently ignore MemCache errors.
|
4
|
+
#
|
5
|
+
# This API is deprecated, please use the Rails.cache API or your own wrapper API
|
6
|
+
# around MemCache.
|
7
|
+
|
8
|
+
module Cache
|
9
|
+
|
10
|
+
##
|
11
|
+
# Try to return a logger object that does not rely
|
12
|
+
# on ActiveRecord for logging.
|
13
|
+
def self.logger
|
14
|
+
@logger ||= if defined? Rails.logger # Rails 2.1 +
|
15
|
+
Rails.logger
|
16
|
+
elsif defined? RAILS_DEFAULT_LOGGER # Rails 1.2.2 +
|
17
|
+
RAILS_DEFAULT_LOGGER
|
18
|
+
else
|
19
|
+
ActiveRecord::Base.logger # ... very old Rails.
|
20
|
+
end
|
21
|
+
end
|
22
|
+
##
|
23
|
+
# Returns the object at +key+ from the cache if successful, or nil if either
|
24
|
+
# the object is not in the cache or if there was an error attermpting to
|
25
|
+
# access the cache.
|
26
|
+
#
|
27
|
+
# If there is a cache miss and a block is given the result of the block will
|
28
|
+
# be stored in the cache with optional +expiry+, using the +add+ method rather
|
29
|
+
# than +set+.
|
30
|
+
|
31
|
+
def self.get(key, expiry = 0)
|
32
|
+
start_time = Time.now
|
33
|
+
value = CACHE.get key
|
34
|
+
elapsed = Time.now - start_time
|
35
|
+
logger.debug('MemCache Get (%0.6f) %s' % [elapsed, key])
|
36
|
+
if value.nil? and block_given? then
|
37
|
+
value = yield
|
38
|
+
add key, value, expiry
|
39
|
+
end
|
40
|
+
value
|
41
|
+
rescue MemCache::MemCacheError => err
|
42
|
+
logger.debug "MemCache Error: #{err.message}"
|
43
|
+
if block_given? then
|
44
|
+
value = yield
|
45
|
+
put key, value, expiry
|
46
|
+
end
|
47
|
+
value
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Sets +value+ in the cache at +key+, with an optional +expiry+ time in
|
52
|
+
# seconds.
|
53
|
+
|
54
|
+
def self.put(key, value, expiry = 0)
|
55
|
+
start_time = Time.now
|
56
|
+
CACHE.set key, value, expiry
|
57
|
+
elapsed = Time.now - start_time
|
58
|
+
logger.debug('MemCache Set (%0.6f) %s' % [elapsed, key])
|
59
|
+
value
|
60
|
+
rescue MemCache::MemCacheError => err
|
61
|
+
ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Sets +value+ in the cache at +key+, with an optional +expiry+ time in
|
67
|
+
# seconds. If +key+ already exists in cache, returns nil.
|
68
|
+
|
69
|
+
def self.add(key, value, expiry = 0)
|
70
|
+
start_time = Time.now
|
71
|
+
response = CACHE.add key, value, expiry
|
72
|
+
elapsed = Time.now - start_time
|
73
|
+
logger.debug('MemCache Add (%0.6f) %s' % [elapsed, key])
|
74
|
+
(response == "STORED\r\n") ? value : nil
|
75
|
+
rescue MemCache::MemCacheError => err
|
76
|
+
ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Deletes +key+ from the cache in +delay+ seconds.
|
82
|
+
|
83
|
+
def self.delete(key, delay = nil)
|
84
|
+
start_time = Time.now
|
85
|
+
CACHE.delete key, delay
|
86
|
+
elapsed = Time.now - start_time
|
87
|
+
logger.debug('MemCache Delete (%0.6f) %s' %
|
88
|
+
[elapsed, key])
|
89
|
+
nil
|
90
|
+
rescue MemCache::MemCacheError => err
|
91
|
+
logger.debug "MemCache Error: #{err.message}"
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Resets all connections to MemCache servers.
|
97
|
+
|
98
|
+
def self.reset
|
99
|
+
CACHE.reset
|
100
|
+
logger.debug 'MemCache Connections Reset'
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
data/performance.txt
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
== 1.5.0, 1.8.6 (default in Rails 2.2 and lower)
|
2
|
+
|
3
|
+
user system total real
|
4
|
+
set:plain:memcache-client 41.550000 0.590000 42.140000 ( 43.740685)
|
5
|
+
set:ruby:memcache-client 41.540000 0.590000 42.130000 ( 43.733796)
|
6
|
+
get:plain:memcache-client 41.920000 0.610000 42.530000 ( 44.031005)
|
7
|
+
get:ruby:memcache-client 41.940000 0.600000 42.540000 ( 44.082447)
|
8
|
+
multiget:ruby:memcache-client 46.120000 0.440000 46.560000 ( 47.354041)
|
9
|
+
missing:ruby:memcache-client 41.490000 0.580000 42.070000 ( 43.610837)
|
10
|
+
mixed:ruby:memcache-client 83.820000 1.190000 85.010000 ( 88.117077)
|
11
|
+
|
12
|
+
|
13
|
+
== 1.7.0, timeout, 1.8.6 (closest to default in Rails 2.3)
|
14
|
+
user system total real
|
15
|
+
set:plain:memcache-client 4.320000 2.280000 6.600000 ( 7.102900)
|
16
|
+
set:ruby:memcache-client 4.400000 2.300000 6.700000 ( 6.856992)
|
17
|
+
get:plain:memcache-client 9.890000 6.830000 16.720000 ( 16.984208)
|
18
|
+
get:ruby:memcache-client 10.040000 6.890000 16.930000 ( 17.141128)
|
19
|
+
multiget:ruby:memcache-client 5.350000 4.110000 9.460000 ( 9.542898)
|
20
|
+
missing:ruby:memcache-client 4.710000 3.180000 7.890000 ( 8.030969)
|
21
|
+
mixed:ruby:memcache-client 14.540000 9.200000 23.740000 ( 24.121824)
|
22
|
+
|
23
|
+
== 1.7.0, timeout, system_timer, 1.8.6
|
24
|
+
user system total real
|
25
|
+
set:plain:memcache-client 3.840000 0.640000 4.480000 ( 4.643790)
|
26
|
+
set:ruby:memcache-client 3.930000 0.650000 4.580000 ( 4.731868)
|
27
|
+
get:plain:memcache-client 8.320000 1.290000 9.610000 ( 9.903877)
|
28
|
+
get:ruby:memcache-client 8.460000 1.310000 9.770000 ( 9.986694)
|
29
|
+
multiget:ruby:memcache-client 4.250000 0.560000 4.810000 ( 4.935326)
|
30
|
+
missing:ruby:memcache-client 3.840000 0.640000 4.480000 ( 4.569696)
|
31
|
+
mixed:ruby:memcache-client 12.400000 1.960000 14.360000 ( 14.857924)
|
32
|
+
|
33
|
+
== 1.7.0, timeout, 1.9.1
|
34
|
+
user system total real
|
35
|
+
set:plain:memcache-client 2.130000 2.150000 4.280000 ( 3.774238)
|
36
|
+
set:ruby:memcache-client 2.230000 2.230000 4.460000 ( 3.883686)
|
37
|
+
get:plain:memcache-client 4.030000 4.250000 8.280000 ( 6.702740)
|
38
|
+
get:ruby:memcache-client 4.090000 4.220000 8.310000 ( 6.749134)
|
39
|
+
multiget:ruby:memcache-client 1.960000 1.840000 3.800000 ( 3.089448)
|
40
|
+
missing:ruby:memcache-client 2.110000 2.210000 4.320000 ( 3.659019)
|
41
|
+
mixed:ruby:memcache-client 6.400000 6.560000 12.960000 ( 11.116317)
|
42
|
+
|
43
|
+
== 1.7.0, no timeout, 1.9.1
|
44
|
+
user system total real
|
45
|
+
set:plain:memcache-client 0.560000 0.320000 0.880000 ( 1.849380)
|
46
|
+
set:ruby:memcache-client 0.630000 0.320000 0.950000 ( 1.968208)
|
47
|
+
get:plain:memcache-client 0.640000 0.330000 0.970000 ( 1.962473)
|
48
|
+
get:ruby:memcache-client 0.690000 0.320000 1.010000 ( 2.002295)
|
49
|
+
multiget:ruby:memcache-client 0.460000 0.110000 0.570000 ( 0.885827)
|
50
|
+
missing:ruby:memcache-client 0.530000 0.320000 0.850000 ( 1.721371)
|
51
|
+
mixed:ruby:memcache-client 1.340000 0.660000 2.000000 ( 3.973213)
|
52
|
+
|
53
|
+
== 1.7.0, no timeout, 1.8.6
|
54
|
+
user system total real
|
55
|
+
set:plain:memcache-client 1.220000 0.310000 1.530000 ( 2.763310)
|
56
|
+
set:ruby:memcache-client 1.270000 0.300000 1.570000 ( 2.806251)
|
57
|
+
get:plain:memcache-client 1.400000 0.300000 1.700000 ( 2.944343)
|
58
|
+
get:ruby:memcache-client 1.450000 0.310000 1.760000 ( 2.997234)
|
59
|
+
multiget:ruby:memcache-client 1.120000 0.110000 1.230000 ( 1.665716)
|
60
|
+
missing:ruby:memcache-client 1.160000 0.300000 1.460000 ( 2.683376)
|
61
|
+
mixed:ruby:memcache-client 2.760000 0.610000 3.370000 ( 5.851047)
|
62
|
+
|
63
|
+
== 1.7.1, timeout, 1.8.6, raw + gets SystemTimer
|
64
|
+
user system total real
|
65
|
+
set:plain:memcache-client 2.670000 0.510000 3.180000 ( 3.489509)
|
66
|
+
set:ruby:memcache-client 2.810000 0.530000 3.340000 ( 3.675955)
|
67
|
+
get:plain:memcache-client 4.380000 0.720000 5.100000 ( 5.400587)
|
68
|
+
get:ruby:memcache-client 4.490000 0.730000 5.220000 ( 5.477543)
|
69
|
+
multiget:ruby:memcache-client 2.570000 0.310000 2.880000 ( 3.034944)
|
70
|
+
missing:ruby:memcache-client 2.800000 0.530000 3.330000 ( 3.547073)
|
71
|
+
mixed:ruby:memcache-client 7.460000 1.250000 8.710000 ( 9.272177)
|
72
|
+
|
73
|
+
== 1.7.1, timeout, 1.9.1, raw + gets Timeout
|
74
|
+
user system total real
|
75
|
+
set:plain:memcache-client 1.370000 1.300000 2.670000 ( 2.708669)
|
76
|
+
set:ruby:memcache-client 1.400000 1.240000 2.640000 ( 2.713737)
|
77
|
+
get:plain:memcache-client 2.070000 2.020000 4.090000 ( 3.950879)
|
78
|
+
get:ruby:memcache-client 2.160000 2.090000 4.250000 ( 3.924613)
|
79
|
+
multiget:ruby:memcache-client 1.080000 0.820000 1.900000 ( 1.744107)
|
80
|
+
missing:ruby:memcache-client 1.330000 1.270000 2.600000 ( 2.547597)
|
81
|
+
mixed:ruby:memcache-client 3.540000 3.270000 6.810000 ( 6.735349)
|
82
|
+
|
83
|
+
== 1.7.1, timeout, 1.8.6, raw + gets SystemTimer, native binary search
|
84
|
+
user system total real
|
85
|
+
set:plain:memcache-client 1.840000 0.450000 2.290000 ( 2.651285)
|
86
|
+
set:ruby:memcache-client 1.960000 0.460000 2.420000 ( 2.712650)
|
87
|
+
get:plain:memcache-client 3.180000 0.630000 3.810000 ( 4.079930)
|
88
|
+
get:ruby:memcache-client 3.290000 0.640000 3.930000 ( 4.242648)
|
89
|
+
multiget:ruby:memcache-client 1.640000 0.250000 1.890000 ( 2.003687)
|
90
|
+
missing:ruby:memcache-client 1.940000 0.450000 2.390000 ( 2.619675)
|
91
|
+
mixed:ruby:memcache-client 5.360000 1.100000 6.460000 ( 7.040998)
|
92
|
+
|
93
|
+
== 1.7.2, timeout, 1.8.6, SystemTimer, native binary search
|
94
|
+
user system total real
|
95
|
+
set:plain:memcache-client 3.260000 0.590000 3.850000 ( 4.067382)
|
96
|
+
set:ruby:memcache-client 3.370000 0.590000 3.960000 ( 4.364004)
|
97
|
+
get:plain:memcache-client 6.740000 1.240000 7.980000 ( 8.586676)
|
98
|
+
get:ruby:memcache-client 6.780000 1.210000 7.990000 ( 8.423400)
|
99
|
+
multiget:ruby:memcache-client 3.480000 0.540000 4.020000 ( 4.288633)
|
100
|
+
missing:ruby:memcache-client 3.250000 0.590000 3.840000 ( 4.043602)
|
101
|
+
mixed:ruby:memcache-client 10.150000 1.810000 11.960000 ( 12.372054)
|
102
|
+
|
103
|
+
== 1.7.4, 1.8.6, buffered and non-blocking IO
|
104
|
+
user system total real
|
105
|
+
set:plain:memcache-client 2.450000 0.790000 3.240000 ( 3.397091)
|
106
|
+
set:ruby:memcache-client 2.490000 0.790000 3.280000 ( 3.555436)
|
107
|
+
get:plain:memcache-client 2.840000 0.810000 3.650000 ( 3.759695)
|
108
|
+
get:ruby:memcache-client 2.890000 0.790000 3.680000 ( 3.778011)
|
109
|
+
multiget:ruby:memcache-client 1.380000 0.280000 1.660000 ( 1.695290)
|
110
|
+
missing:ruby:memcache-client 2.380000 0.780000 3.160000 ( 3.251136)
|
111
|
+
mixed:ruby:memcache-client 5.360000 1.600000 6.960000 ( 7.189314)
|
112
|
+
|
113
|
+
== memcached 0.13 + libmemcached 0.25.4 versus memcache-client 1.7.4
|
114
|
+
|
115
|
+
user system total real
|
116
|
+
set:plain:noblock:memcached 0.090000 0.030000 0.120000 ( 0.277929)
|
117
|
+
set:plain:memcached 0.220000 0.270000 0.490000 ( 1.251547)
|
118
|
+
set:plain:memcache-client 0.610000 0.270000 0.880000 ( 1.670718)
|
119
|
+
set:ruby:noblock:memcached 0.150000 0.020000 0.170000 ( 0.309201)
|
120
|
+
set:ruby:memcached 0.300000 0.290000 0.590000 ( 1.390354)
|
121
|
+
set:ruby:memcache-client 0.670000 0.270000 0.940000 ( 1.713558)
|
122
|
+
get:plain:memcached 0.240000 0.270000 0.510000 ( 1.169909)
|
123
|
+
get:plain:memcache-client 0.850000 0.270000 1.120000 ( 1.885270)
|
124
|
+
get:ruby:memcached 0.270000 0.280000 0.550000 ( 1.229705)
|
125
|
+
get:ruby:memcache-client 0.890000 0.260000 1.150000 ( 1.861660)
|
126
|
+
multiget:ruby:memcached 0.190000 0.090000 0.280000 ( 0.396264)
|
127
|
+
multiget:ruby:memcache-client 0.530000 0.100000 0.630000 ( 0.901016)
|
128
|
+
missing:ruby:memcached 0.280000 0.290000 0.570000 ( 1.254400)
|
129
|
+
missing:ruby:memcached:inline 0.300000 0.290000 0.590000 ( 1.235122)
|
130
|
+
missing:ruby:memcache-client 0.570000 0.250000 0.820000 ( 1.461293)
|
131
|
+
mixed:ruby:noblock:memcached 0.540000 0.620000 1.160000 ( 2.429200)
|
132
|
+
mixed:ruby:memcached 0.580000 0.570000 1.150000 ( 2.610819)
|
133
|
+
mixed:ruby:memcache-client 1.580000 0.540000 2.120000 ( 3.632775)
|
134
|
+
|
135
|
+
== 1.7.6, 1.8.7 64-bit (Snow Leopard), SystemTimer
|
136
|
+
user system total real
|
137
|
+
set:plain:memcache-client 3.070000 0.380000 3.450000 ( 3.643275)
|
138
|
+
set:ruby:memcache-client 3.140000 0.370000 3.510000 ( 3.698602)
|
139
|
+
get:plain:memcache-client 3.480000 0.360000 3.840000 ( 3.983941)
|
140
|
+
get:ruby:memcache-client 3.540000 0.360000 3.900000 ( 4.034308)
|
141
|
+
multiget:ruby:memcache-client 1.690000 0.140000 1.830000 ( 1.889290)
|
142
|
+
missing:ruby:memcache-client 3.070000 0.360000 3.430000 ( 3.571754)
|
143
|
+
mixed:ruby:memcache-client 6.720000 0.750000 7.470000 ( 7.838771)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
HERE = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift "#{HERE}/../lib"
|
3
|
+
#$LOAD_PATH << "/Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/active_support/vendor/memcache-client-1.5.1"
|
4
|
+
|
5
|
+
require 'benchmark'
|
6
|
+
require 'rubygems'
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
$TESTING = true
|
10
|
+
require 'memcache' if not defined?(MemCache)
|
11
|
+
|
12
|
+
class TestBenchmark < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
puts "Testing #{MemCache::VERSION}"
|
16
|
+
# We'll use a simple @value to try to avoid spending time in Marshal,
|
17
|
+
# which is a constant penalty that both clients have to pay
|
18
|
+
@value = []
|
19
|
+
@marshalled = Marshal.dump(@value)
|
20
|
+
|
21
|
+
@opts = [
|
22
|
+
['127.0.0.1:11211', 'localhost:11211'],
|
23
|
+
{
|
24
|
+
:namespace => "namespace",
|
25
|
+
# :no_reply => true,
|
26
|
+
# :timeout => nil,
|
27
|
+
}
|
28
|
+
]
|
29
|
+
@key1 = "Short"
|
30
|
+
@key2 = "Sym1-2-3::45"*8
|
31
|
+
@key3 = "Long"*40
|
32
|
+
@key4 = "Medium"*8
|
33
|
+
# 5 and 6 are only used for multiget miss test
|
34
|
+
@key5 = "Medium2"*8
|
35
|
+
@key6 = "Long3"*40
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_benchmark
|
39
|
+
Benchmark.bm(31) do |x|
|
40
|
+
|
41
|
+
n = 2500
|
42
|
+
# n = 1000
|
43
|
+
|
44
|
+
@m = MemCache.new(*@opts)
|
45
|
+
x.report("set:plain:memcache-client") do
|
46
|
+
n.times do
|
47
|
+
@m.set @key1, @marshalled, 0, true
|
48
|
+
@m.set @key2, @marshalled, 0, true
|
49
|
+
@m.set @key3, @marshalled, 0, true
|
50
|
+
@m.set @key1, @marshalled, 0, true
|
51
|
+
@m.set @key2, @marshalled, 0, true
|
52
|
+
@m.set @key3, @marshalled, 0, true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@m = MemCache.new(*@opts)
|
57
|
+
x.report("set:ruby:memcache-client") do
|
58
|
+
n.times do
|
59
|
+
@m.set @key1, @value
|
60
|
+
@m.set @key2, @value
|
61
|
+
@m.set @key3, @value
|
62
|
+
@m.set @key1, @value
|
63
|
+
@m.set @key2, @value
|
64
|
+
@m.set @key3, @value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@m = MemCache.new(*@opts)
|
69
|
+
x.report("get:plain:memcache-client") do
|
70
|
+
n.times do
|
71
|
+
@m.get @key1, true
|
72
|
+
@m.get @key2, true
|
73
|
+
@m.get @key3, true
|
74
|
+
@m.get @key1, true
|
75
|
+
@m.get @key2, true
|
76
|
+
@m.get @key3, true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
@m = MemCache.new(*@opts)
|
81
|
+
x.report("get:ruby:memcache-client") do
|
82
|
+
n.times do
|
83
|
+
@m.get @key1
|
84
|
+
@m.get @key2
|
85
|
+
@m.get @key3
|
86
|
+
@m.get @key1
|
87
|
+
@m.get @key2
|
88
|
+
@m.get @key3
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
@m = MemCache.new(*@opts)
|
93
|
+
x.report("multiget:ruby:memcache-client") do
|
94
|
+
n.times do
|
95
|
+
# We don't use the keys array because splat is slow
|
96
|
+
@m.get_multi @key1, @key2, @key3, @key4, @key5, @key6
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
@m = MemCache.new(*@opts)
|
101
|
+
x.report("missing:ruby:memcache-client") do
|
102
|
+
n.times do
|
103
|
+
begin @m.delete @key1; rescue; end
|
104
|
+
begin @m.get @key1; rescue; end
|
105
|
+
begin @m.delete @key2; rescue; end
|
106
|
+
begin @m.get @key2; rescue; end
|
107
|
+
begin @m.delete @key3; rescue; end
|
108
|
+
begin @m.get @key3; rescue; end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
@m = MemCache.new(*@opts)
|
113
|
+
x.report("mixed:ruby:memcache-client") do
|
114
|
+
n.times do
|
115
|
+
@m.set @key1, @value
|
116
|
+
@m.set @key2, @value
|
117
|
+
@m.set @key3, @value
|
118
|
+
@m.get @key1
|
119
|
+
@m.get @key2
|
120
|
+
@m.get @key3
|
121
|
+
@m.set @key1, @value
|
122
|
+
@m.get @key1
|
123
|
+
@m.set @key2, @value
|
124
|
+
@m.get @key2
|
125
|
+
@m.set @key3, @value
|
126
|
+
@m.get @key3
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
assert true
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
data/test/test_mem_cache.rb
CHANGED
@@ -1100,6 +1100,25 @@ class TestMemCache < Test::Unit::TestCase
|
|
1100
1100
|
assert_match(/test value/, output)
|
1101
1101
|
end
|
1102
1102
|
|
1103
|
+
def test_namespace_separator
|
1104
|
+
cache = MemCache.new :namespace => 'ns', :namespace_separator => ''
|
1105
|
+
|
1106
|
+
server = FakeServer.new
|
1107
|
+
server.socket.data.write "STORED\r\n"
|
1108
|
+
server.socket.data.rewind
|
1109
|
+
|
1110
|
+
cache.servers = []
|
1111
|
+
cache.servers << server
|
1112
|
+
|
1113
|
+
assert_nothing_raised do
|
1114
|
+
cache.set "test", "test value"
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
output = server.socket.written.string
|
1118
|
+
assert_match(/set nstest/, output)
|
1119
|
+
assert_match(/test value/, output)
|
1120
|
+
end
|
1121
|
+
|
1103
1122
|
def test_basic_unthreaded_operations_should_work
|
1104
1123
|
cache = MemCache.new :multithread => false,
|
1105
1124
|
:namespace => 'my_namespace',
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcache-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.6
|
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: 2009-
|
14
|
+
date: 2009-11-03 00:00:00 -06:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
@@ -21,23 +21,29 @@ executables: []
|
|
21
21
|
|
22
22
|
extensions: []
|
23
23
|
|
24
|
-
extra_rdoc_files:
|
25
|
-
|
24
|
+
extra_rdoc_files:
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.rdoc
|
26
27
|
files:
|
27
28
|
- FAQ.rdoc
|
28
|
-
- README.rdoc
|
29
|
-
- LICENSE.txt
|
30
29
|
- History.rdoc
|
30
|
+
- LICENSE.txt
|
31
|
+
- README.rdoc
|
31
32
|
- Rakefile
|
32
|
-
-
|
33
|
+
- VERSION.yml
|
33
34
|
- lib/continuum_native.rb
|
35
|
+
- lib/memcache.rb
|
36
|
+
- lib/memcache_util.rb
|
37
|
+
- performance.txt
|
38
|
+
- test/test_benchmark.rb
|
39
|
+
- test/test_mem_cache.rb
|
34
40
|
has_rdoc: true
|
35
41
|
homepage: http://github.com/mperham/memcache-client
|
36
42
|
licenses: []
|
37
43
|
|
38
44
|
post_install_message:
|
39
|
-
rdoc_options:
|
40
|
-
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
41
47
|
require_paths:
|
42
48
|
- lib
|
43
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -60,4 +66,5 @@ signing_key:
|
|
60
66
|
specification_version: 3
|
61
67
|
summary: A Ruby library for accessing memcached.
|
62
68
|
test_files:
|
69
|
+
- test/test_benchmark.rb
|
63
70
|
- test/test_mem_cache.rb
|