jjp-memcache-client 1.8.7
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/FAQ.rdoc +32 -0
- data/History.rdoc +288 -0
- data/LICENSE.txt +28 -0
- data/README.rdoc +70 -0
- data/Rakefile +42 -0
- data/bin/memcached_top +56 -0
- data/lib/continuum_native.rb +41 -0
- data/lib/memcache.rb +1210 -0
- data/lib/memcache/event_machine.rb +173 -0
- data/lib/memcache/version.rb +6 -0
- data/lib/memcache_util.rb +105 -0
- data/performance.txt +143 -0
- data/test/test_benchmark.rb +142 -0
- data/test/test_event_machine.rb +110 -0
- data/test/test_mem_cache.rb +1323 -0
- metadata +72 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
# Extensions for using memcache-client with EventMachine
|
2
|
+
|
3
|
+
raise "memcache/event_machine requires Ruby 1.9" if RUBY_VERSION < '1.9'
|
4
|
+
|
5
|
+
require 'memcache'
|
6
|
+
require 'eventmachine'
|
7
|
+
require 'fiber'
|
8
|
+
|
9
|
+
class MemCache
|
10
|
+
|
11
|
+
# Since we are working in a single Thread, multiple Fiber environment,
|
12
|
+
# disable the multithread Mutex as it will not work.
|
13
|
+
# DEFAULT_OPTIONS[:multithread] = false
|
14
|
+
|
15
|
+
module EventedServer
|
16
|
+
|
17
|
+
def fiber_key
|
18
|
+
@fiber_key ||= "memcached-#{@host}-#{@port}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def socket
|
22
|
+
sock = Thread.current[fiber_key]
|
23
|
+
return sock if sock and not sock.closed?
|
24
|
+
|
25
|
+
Thread.current[fiber_key] = nil
|
26
|
+
|
27
|
+
# If the host was dead, don't retry for a while.
|
28
|
+
return if @retry and @retry > Time.now
|
29
|
+
|
30
|
+
Thread.current[fiber_key] ||= begin
|
31
|
+
sock = EM::SocketConnection.connect(@host, @port, @timeout)
|
32
|
+
yielding = true
|
33
|
+
fiber = Fiber.current
|
34
|
+
sock.callback do
|
35
|
+
@status = 'CONNECTED'
|
36
|
+
@retry = nil
|
37
|
+
yielding = false
|
38
|
+
fiber.resume if Fiber.current != fiber
|
39
|
+
end
|
40
|
+
sock.errback do
|
41
|
+
sock = nil
|
42
|
+
yielding = false
|
43
|
+
fiber.resume if Fiber.current != fiber
|
44
|
+
end
|
45
|
+
Fiber.yield if yielding
|
46
|
+
sock
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def close
|
51
|
+
sock = Thread.current[fiber_key]
|
52
|
+
if sock
|
53
|
+
sock.close if !sock.closed?
|
54
|
+
Thread.current[fiber_key] = nil
|
55
|
+
end
|
56
|
+
@retry = nil
|
57
|
+
@status = "NOT CONNECTED"
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module EM
|
64
|
+
module SocketConnection
|
65
|
+
include EM::Deferrable
|
66
|
+
|
67
|
+
def self.connect(host, port, timeout)
|
68
|
+
EM.connect(host, port, self) do |conn|
|
69
|
+
conn.pending_connect_timeout = timeout
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize
|
74
|
+
@connected = false
|
75
|
+
@index = 0
|
76
|
+
@buf = ''
|
77
|
+
end
|
78
|
+
|
79
|
+
def closed?
|
80
|
+
!@connected
|
81
|
+
end
|
82
|
+
|
83
|
+
def close
|
84
|
+
@connected = false
|
85
|
+
close_connection(true)
|
86
|
+
end
|
87
|
+
|
88
|
+
def write(buf)
|
89
|
+
send_data(buf)
|
90
|
+
end
|
91
|
+
|
92
|
+
def read(size)
|
93
|
+
if can_read?(size)
|
94
|
+
yank(size)
|
95
|
+
else
|
96
|
+
fiber = Fiber.current
|
97
|
+
@size = size
|
98
|
+
@callback = proc { |data|
|
99
|
+
fiber.resume(data)
|
100
|
+
}
|
101
|
+
# TODO Can leak fiber if the connection dies while
|
102
|
+
# this fiber is yielded, waiting for data
|
103
|
+
Fiber.yield
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
SEP = "\r\n"
|
108
|
+
|
109
|
+
def gets
|
110
|
+
while true
|
111
|
+
# Read to ensure we have some data in the buffer
|
112
|
+
line = read(2)
|
113
|
+
# Reset the buffer index to zero
|
114
|
+
@buf = @buf.slice(@index..-1)
|
115
|
+
@index = 0
|
116
|
+
if eol = @buf.index(SEP)
|
117
|
+
line << yank(eol + SEP.size)
|
118
|
+
break
|
119
|
+
else
|
120
|
+
# EOL not in the current buffer
|
121
|
+
line << yank(@buf.size)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
line
|
125
|
+
end
|
126
|
+
|
127
|
+
def can_read?(size)
|
128
|
+
@buf.size >= @index + size
|
129
|
+
end
|
130
|
+
|
131
|
+
# EM callbacks
|
132
|
+
|
133
|
+
def receive_data(data)
|
134
|
+
@buf << data
|
135
|
+
|
136
|
+
if @callback and can_read?(@size)
|
137
|
+
callback = @callback
|
138
|
+
data = yank(@size)
|
139
|
+
@callback = @size = nil
|
140
|
+
callback.call(data)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def post_init
|
145
|
+
@connected = true
|
146
|
+
succeed
|
147
|
+
end
|
148
|
+
|
149
|
+
def unbind
|
150
|
+
if @connected
|
151
|
+
@connected = false
|
152
|
+
else
|
153
|
+
fail
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
BUFFER_SIZE = 4096
|
160
|
+
|
161
|
+
def yank(len)
|
162
|
+
data = @buf.slice(@index, len)
|
163
|
+
@index += len
|
164
|
+
@index = @buf.size if @index > @buf.size
|
165
|
+
if @index >= BUFFER_SIZE
|
166
|
+
@buf = @buf.slice(@index..-1)
|
167
|
+
@index = 0
|
168
|
+
end
|
169
|
+
data
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
@@ -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,142 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'benchmark'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
$TESTING = true
|
6
|
+
require 'memcache'
|
7
|
+
|
8
|
+
class TestBenchmark < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
puts "Testing #{MemCache::VERSION}"
|
12
|
+
# We'll use a simple @value to try to avoid spending time in Marshal,
|
13
|
+
# which is a constant penalty that both clients have to pay
|
14
|
+
@value = []
|
15
|
+
@marshalled = Marshal.dump(@value)
|
16
|
+
|
17
|
+
@opts = [
|
18
|
+
['127.0.0.1:11211', 'localhost:11211'],
|
19
|
+
{
|
20
|
+
:namespace => "namespace",
|
21
|
+
# :no_reply => true,
|
22
|
+
# :timeout => nil,
|
23
|
+
}
|
24
|
+
]
|
25
|
+
@key1 = "Short"
|
26
|
+
@key2 = "Sym1-2-3::45"*8
|
27
|
+
@key3 = "Long"*40
|
28
|
+
@key4 = "Medium"*8
|
29
|
+
# 5 and 6 are only used for multiget miss test
|
30
|
+
@key5 = "Medium2"*8
|
31
|
+
@key6 = "Long3"*40
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_em
|
35
|
+
return if RUBY_VERSION < '1.9'
|
36
|
+
require 'eventmachine'
|
37
|
+
require 'memcache/event_machine'
|
38
|
+
puts "with EventMachine"
|
39
|
+
EM.run do
|
40
|
+
Fiber.new do
|
41
|
+
test_benchmark
|
42
|
+
EM.stop
|
43
|
+
end.resume
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_benchmark
|
48
|
+
Benchmark.bm(31) do |x|
|
49
|
+
|
50
|
+
n = 2500
|
51
|
+
|
52
|
+
@m = MemCache.new(*@opts)
|
53
|
+
x.report("set:plain:memcache-client") do
|
54
|
+
n.times do
|
55
|
+
@m.set @key1, @marshalled, 0, true
|
56
|
+
@m.set @key2, @marshalled, 0, true
|
57
|
+
@m.set @key3, @marshalled, 0, true
|
58
|
+
@m.set @key1, @marshalled, 0, true
|
59
|
+
@m.set @key2, @marshalled, 0, true
|
60
|
+
@m.set @key3, @marshalled, 0, true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@m = MemCache.new(*@opts)
|
65
|
+
x.report("set:ruby:memcache-client") do
|
66
|
+
n.times do
|
67
|
+
@m.set @key1, @value
|
68
|
+
@m.set @key2, @value
|
69
|
+
@m.set @key3, @value
|
70
|
+
@m.set @key1, @value
|
71
|
+
@m.set @key2, @value
|
72
|
+
@m.set @key3, @value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@m = MemCache.new(*@opts)
|
77
|
+
x.report("get:plain:memcache-client") do
|
78
|
+
n.times do
|
79
|
+
@m.get @key1, true
|
80
|
+
@m.get @key2, true
|
81
|
+
@m.get @key3, true
|
82
|
+
@m.get @key1, true
|
83
|
+
@m.get @key2, true
|
84
|
+
@m.get @key3, true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
@m = MemCache.new(*@opts)
|
89
|
+
x.report("get:ruby:memcache-client") do
|
90
|
+
n.times do
|
91
|
+
@m.get @key1
|
92
|
+
@m.get @key2
|
93
|
+
@m.get @key3
|
94
|
+
@m.get @key1
|
95
|
+
@m.get @key2
|
96
|
+
@m.get @key3
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
@m = MemCache.new(*@opts)
|
101
|
+
x.report("multiget:ruby:memcache-client") do
|
102
|
+
n.times do
|
103
|
+
# We don't use the keys array because splat is slow
|
104
|
+
@m.get_multi @key1, @key2, @key3, @key4, @key5, @key6
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
@m = MemCache.new(*@opts)
|
109
|
+
x.report("missing:ruby:memcache-client") do
|
110
|
+
n.times do
|
111
|
+
begin @m.delete @key1; rescue; end
|
112
|
+
begin @m.get @key1; rescue; end
|
113
|
+
begin @m.delete @key2; rescue; end
|
114
|
+
begin @m.get @key2; rescue; end
|
115
|
+
begin @m.delete @key3; rescue; end
|
116
|
+
begin @m.get @key3; rescue; end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
@m = MemCache.new(*@opts)
|
121
|
+
x.report("mixed:ruby:memcache-client") do
|
122
|
+
n.times do
|
123
|
+
@m.set @key1, @value
|
124
|
+
@m.set @key2, @value
|
125
|
+
@m.set @key3, @value
|
126
|
+
@m.get @key1
|
127
|
+
@m.get @key2
|
128
|
+
@m.get @key3
|
129
|
+
@m.set @key1, @value
|
130
|
+
@m.get @key1
|
131
|
+
@m.set @key2, @value
|
132
|
+
@m.get @key2
|
133
|
+
@m.set @key3, @value
|
134
|
+
@m.get @key3
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
assert true
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|