memcache 1.2.0 → 1.2.1
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/.gitignore +12 -1
- data/README.rdoc +65 -11
- data/Rakefile +14 -0
- data/VERSION.yml +2 -2
- data/bench/benchmark.rb +126 -0
- data/ext/extconf.rb +51 -2
- data/ext/libmemcached-0.38.tar.gz +0 -0
- data/ext/native_server.c +575 -0
- data/lib/memcache/base.rb +65 -0
- data/lib/memcache/local_server.rb +7 -53
- data/lib/memcache/migration.rb +7 -6
- data/lib/memcache/null_server.rb +1 -1
- data/lib/memcache/pg_server.rb +37 -20
- data/lib/memcache/{segmented_server.rb → segmented.rb} +25 -15
- data/lib/memcache/server.rb +44 -56
- data/lib/memcache.rb +131 -83
- data/test/memcache_local_server_test.rb +1 -1
- data/test/memcache_native_server_test.rb +31 -0
- data/test/memcache_null_server_test.rb +16 -8
- data/test/memcache_segmented_native_server_test.rb +18 -0
- data/test/memcache_segmented_server_test.rb +6 -9
- data/test/memcache_server_test.rb +9 -11
- data/test/memcache_server_test_helper.rb +89 -49
- data/test/memcache_test.rb +11 -19
- data/test/test_helper.rb +34 -9
- metadata +12 -4
- data/memcache.gemspec +0 -69
data/lib/memcache.rb
CHANGED
@@ -1,43 +1,82 @@
|
|
1
1
|
require 'zlib'
|
2
2
|
|
3
3
|
$:.unshift(File.dirname(__FILE__))
|
4
|
+
require 'memcache/base'
|
4
5
|
require 'memcache/server'
|
5
6
|
require 'memcache/local_server'
|
6
|
-
|
7
|
+
begin
|
8
|
+
require 'memcache/native_server'
|
9
|
+
rescue LoadError => e
|
10
|
+
puts "memcache is not using native bindings. for faster performance, compile extensions by hand or install as a local gem."
|
11
|
+
end
|
12
|
+
require 'memcache/segmented'
|
7
13
|
|
8
14
|
class Memcache
|
9
15
|
DEFAULT_EXPIRY = 0
|
10
16
|
LOCK_TIMEOUT = 5
|
11
17
|
WRITE_LOCK_WAIT = 1
|
12
18
|
|
13
|
-
attr_reader :default_expiry, :
|
19
|
+
attr_reader :default_expiry, :namespace, :servers, :backup
|
20
|
+
|
21
|
+
class Error < StandardError; end
|
22
|
+
class ConnectionError < Error
|
23
|
+
def initialize(e)
|
24
|
+
if e.kind_of?(String)
|
25
|
+
super
|
26
|
+
else
|
27
|
+
super("(#{e.class}) #{e.message}")
|
28
|
+
set_backtrace(e.backtrace)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
class ServerError < Error; end
|
33
|
+
class ClientError < Error; end
|
14
34
|
|
15
35
|
def initialize(opts)
|
16
|
-
@default_expiry
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
server
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
36
|
+
@default_expiry = opts[:default_expiry] || DEFAULT_EXPIRY
|
37
|
+
@backup = opts[:backup] # for multi-level caches
|
38
|
+
@hash_with_prefix = opts[:hash_with_prefix].nil? ? true : opts[:hash_with_prefix]
|
39
|
+
|
40
|
+
if opts[:native]
|
41
|
+
native_opts = {}
|
42
|
+
native_opts[:servers] = (opts[:servers] || [ opts[:server] ]).collect do |server|
|
43
|
+
server.is_a?(Hash) ? "#{server[:host]}:#{server[:port]}" : server
|
44
|
+
end
|
45
|
+
native_opts[:hash] = opts[:hash] || :crc
|
46
|
+
native_opts[:hash_with_prefix] = @hash_with_prefix
|
47
|
+
native_opts[:binary] = opts[:binary]
|
48
|
+
|
49
|
+
server_class = opts[:segment_large_values] ? SegmentedNativeServer : NativeServer
|
50
|
+
@servers = [server_class.new(native_opts)]
|
51
|
+
else
|
52
|
+
raise "only CRC hashing is supported unless :native => true" if opts[:hash] and opts[:hash] != :crc
|
53
|
+
|
54
|
+
server_class = opts[:segment_large_values] ? SegmentedServer : Server
|
55
|
+
@servers = (opts[:servers] || [ opts[:server] ]).collect do |server|
|
56
|
+
case server
|
57
|
+
when Hash
|
58
|
+
server = server_class.new(opts.merge(server))
|
59
|
+
when String
|
60
|
+
host, port = server.split(':')
|
61
|
+
server = server_class.new(opts.merge(:host => host, :port => port))
|
62
|
+
when Class
|
63
|
+
server = server.new
|
64
|
+
when :local
|
65
|
+
server = Memcache::LocalServer.new
|
66
|
+
end
|
67
|
+
server
|
31
68
|
end
|
32
|
-
server
|
33
69
|
end
|
70
|
+
|
71
|
+
@server = @servers.first if @servers.size == 1 and @backup.nil?
|
72
|
+
self.namespace = opts[:namespace] if opts[:namespace]
|
34
73
|
end
|
35
74
|
|
36
75
|
def clone
|
37
76
|
self.class.new(
|
38
|
-
:default_expiry
|
39
|
-
:
|
40
|
-
:servers
|
77
|
+
:default_expiry => default_expiry,
|
78
|
+
:namespace => namespace,
|
79
|
+
:servers => servers.collect {|s| s.clone}
|
41
80
|
)
|
42
81
|
end
|
43
82
|
|
@@ -45,23 +84,21 @@ class Memcache
|
|
45
84
|
"<Memcache: %d servers, ns: %p>" % [@servers.length, namespace]
|
46
85
|
end
|
47
86
|
|
48
|
-
def namespace
|
49
|
-
@namespace || default_namespace
|
50
|
-
end
|
51
|
-
|
52
87
|
def namespace=(namespace)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
88
|
+
@namespace = namespace
|
89
|
+
prefix = "#{namespace}:"
|
90
|
+
servers.each do |server|
|
91
|
+
server.prefix = prefix
|
57
92
|
end
|
93
|
+
backup.namespace = @namespace if backup
|
94
|
+
@namespace
|
58
95
|
end
|
59
96
|
|
60
97
|
def in_namespace(namespace)
|
61
98
|
# Temporarily change the namespace for convenience.
|
62
99
|
begin
|
63
|
-
old_namespace
|
64
|
-
self.namespace = "#{old_namespace}
|
100
|
+
old_namespace = self.namespace
|
101
|
+
self.namespace = "#{old_namespace}:#{namespace}"
|
65
102
|
yield
|
66
103
|
ensure
|
67
104
|
self.namespace = old_namespace
|
@@ -69,19 +106,21 @@ class Memcache
|
|
69
106
|
end
|
70
107
|
|
71
108
|
def get(keys, opts = {})
|
72
|
-
raise 'opts must be hash' unless opts.
|
109
|
+
raise 'opts must be hash' unless opts.instance_of?(Hash)
|
73
110
|
|
74
|
-
if keys.
|
111
|
+
if keys.instance_of?(Array)
|
112
|
+
keys.collect! {|key| key.to_s}
|
75
113
|
multi_get(keys, opts)
|
76
114
|
else
|
77
|
-
key =
|
78
|
-
|
115
|
+
key = keys.to_s
|
79
116
|
if opts[:expiry]
|
80
117
|
value = server(key).gets(key)
|
81
|
-
|
118
|
+
cas(key, value, :raw => true, :cas => value.memcache_cas, :expiry => opts[:expiry]) if value
|
82
119
|
else
|
83
120
|
value = server(key).get(key, opts[:cas])
|
84
121
|
end
|
122
|
+
|
123
|
+
return backup.get(key, opts) if backup and value.nil?
|
85
124
|
opts[:raw] ? value : unmarshal(value, key)
|
86
125
|
end
|
87
126
|
end
|
@@ -92,10 +131,11 @@ class Memcache
|
|
92
131
|
|
93
132
|
def set(key, value, opts = {})
|
94
133
|
opts = compatible_opts(opts)
|
134
|
+
key = key.to_s
|
135
|
+
backup.set(key, value, opts) if backup
|
95
136
|
|
96
137
|
expiry = opts[:expiry] || default_expiry
|
97
138
|
flags = opts[:flags] || 0
|
98
|
-
key = cache_key(key)
|
99
139
|
data = marshal(value, opts)
|
100
140
|
server(key).set(key, data, expiry, flags)
|
101
141
|
value
|
@@ -107,60 +147,67 @@ class Memcache
|
|
107
147
|
|
108
148
|
def add(key, value, opts = {})
|
109
149
|
opts = compatible_opts(opts)
|
150
|
+
key = key.to_s
|
151
|
+
backup.add(key, value, opts) if backup
|
110
152
|
|
111
153
|
expiry = opts[:expiry] || default_expiry
|
112
154
|
flags = opts[:flags] || 0
|
113
|
-
key = cache_key(key)
|
114
155
|
data = marshal(value, opts)
|
115
156
|
server(key).add(key, data, expiry, flags) && value
|
116
157
|
end
|
117
158
|
|
118
159
|
def replace(key, value, opts = {})
|
119
160
|
opts = compatible_opts(opts)
|
161
|
+
key = key.to_s
|
162
|
+
backup.replace(key, value, opts) if backup
|
120
163
|
|
121
164
|
expiry = opts[:expiry] || default_expiry
|
122
165
|
flags = opts[:flags] || 0
|
123
|
-
key = cache_key(key)
|
124
166
|
data = marshal(value, opts)
|
125
167
|
server(key).replace(key, data, expiry, flags) && value
|
126
168
|
end
|
127
169
|
|
128
|
-
def cas(key, value, opts
|
129
|
-
raise 'opts must be hash' unless opts.
|
170
|
+
def cas(key, value, opts)
|
171
|
+
raise 'opts must be hash' unless opts.instance_of?(Hash)
|
172
|
+
key = key.to_s
|
173
|
+
backup.cas(key, value, opts) if backup
|
130
174
|
|
131
175
|
expiry = opts[:expiry] || default_expiry
|
132
176
|
flags = opts[:flags] || 0
|
133
|
-
key = cache_key(key)
|
134
177
|
data = marshal(value, opts)
|
135
178
|
server(key).cas(key, data, opts[:cas], expiry, flags) && value
|
136
179
|
end
|
137
180
|
|
138
181
|
def append(key, value)
|
139
|
-
key =
|
182
|
+
key = key.to_s
|
183
|
+
backup.append(key, value) if backup
|
140
184
|
server(key).append(key, value)
|
141
185
|
end
|
142
186
|
|
143
187
|
def prepend(key, value)
|
144
|
-
key =
|
188
|
+
key = key.to_s
|
189
|
+
backup.prepend(key, value) if backup
|
145
190
|
server(key).prepend(key, value)
|
146
191
|
end
|
147
192
|
|
148
193
|
def count(key)
|
149
|
-
key
|
150
|
-
server(key).get(key).to_i
|
194
|
+
get(key, :raw => true).to_i
|
151
195
|
end
|
152
196
|
|
153
197
|
def incr(key, amount = 1)
|
154
|
-
key =
|
198
|
+
key = key.to_s
|
199
|
+
backup.incr(key, amount) if backup
|
155
200
|
server(key).incr(key, amount)
|
156
201
|
end
|
157
202
|
|
158
203
|
def decr(key, amount = 1)
|
159
|
-
key =
|
204
|
+
key = key.to_s
|
205
|
+
backup.decr(key, amount) if backup
|
160
206
|
server(key).decr(key, amount)
|
161
207
|
end
|
162
208
|
|
163
209
|
def update(key, opts = {})
|
210
|
+
key = key.to_s
|
164
211
|
value = get(key, :cas => true)
|
165
212
|
if value
|
166
213
|
cas(key, yield(value), opts.merge!(:cas => value.memcache_cas))
|
@@ -171,6 +218,7 @@ class Memcache
|
|
171
218
|
|
172
219
|
def get_or_add(key, *args)
|
173
220
|
# Pseudo-atomic get and update.
|
221
|
+
key = key.to_s
|
174
222
|
if block_given?
|
175
223
|
opts = args[0] || {}
|
176
224
|
get(key) || add(key, yield, opts) || get(key)
|
@@ -181,6 +229,7 @@ class Memcache
|
|
181
229
|
end
|
182
230
|
|
183
231
|
def get_or_set(key, *args)
|
232
|
+
key = key.to_s
|
184
233
|
if block_given?
|
185
234
|
opts = args[0] || {}
|
186
235
|
get(key) || set(key, yield, opts)
|
@@ -192,8 +241,7 @@ class Memcache
|
|
192
241
|
|
193
242
|
def get_some(keys, opts = {})
|
194
243
|
keys = keys.collect {|key| key.to_s}
|
195
|
-
|
196
|
-
records = opts[:disable] ? {} : self.get(keys, opts)
|
244
|
+
records = opts[:disable] ? {} : self.multi_get(keys, opts)
|
197
245
|
if opts[:validation]
|
198
246
|
records.delete_if do |key, value|
|
199
247
|
not opts[:validation].call(key, value)
|
@@ -239,7 +287,8 @@ class Memcache
|
|
239
287
|
end
|
240
288
|
|
241
289
|
def delete(key)
|
242
|
-
key =
|
290
|
+
key = key.to_s
|
291
|
+
backup.delete(key) if backup
|
243
292
|
server(key).delete(key)
|
244
293
|
end
|
245
294
|
|
@@ -270,7 +319,7 @@ class Memcache
|
|
270
319
|
stats
|
271
320
|
end
|
272
321
|
end
|
273
|
-
|
322
|
+
|
274
323
|
alias clear flush_all
|
275
324
|
|
276
325
|
def [](key)
|
@@ -307,50 +356,49 @@ protected
|
|
307
356
|
|
308
357
|
def compatible_opts(opts)
|
309
358
|
# Support passing expiry instead of opts. This may be deprecated in the future.
|
310
|
-
opts.
|
359
|
+
opts.instance_of?(Hash) ? opts : {:expiry => opts}
|
311
360
|
end
|
312
361
|
|
313
362
|
def multi_get(keys, opts = {})
|
314
363
|
return {} if keys.empty?
|
315
|
-
|
316
|
-
key_to_input_key = {}
|
317
|
-
keys_by_server = Hash.new { |h,k| h[k] = [] }
|
318
|
-
|
319
|
-
# Store keys by servers. Also store a mapping from cache key to input key.
|
320
|
-
keys.each do |input_key|
|
321
|
-
key = cache_key(input_key)
|
322
|
-
server = server(key)
|
323
|
-
key_to_input_key[key] = input_key.to_s
|
324
|
-
keys_by_server[server] << key
|
325
|
-
end
|
326
|
-
|
327
|
-
# Fetch and combine the results. Also, map the cache keys back to the input keys.
|
364
|
+
|
328
365
|
results = {}
|
329
|
-
|
366
|
+
fetch_results = lambda do |server, keys|
|
330
367
|
server.get(keys, opts[:cas]).each do |key, value|
|
331
|
-
|
332
|
-
results[input_key] = opts[:raw] ? value : unmarshal(value, key)
|
368
|
+
results[key] = opts[:raw] ? value : unmarshal(value, key)
|
333
369
|
end
|
334
370
|
end
|
335
|
-
results
|
336
|
-
end
|
337
371
|
|
338
|
-
|
339
|
-
|
340
|
-
if namespace.nil? then
|
341
|
-
safe_key
|
372
|
+
if @server
|
373
|
+
fetch_results.call(@server, keys)
|
342
374
|
else
|
343
|
-
|
375
|
+
keys_by_server = Hash.new { |h,k| h[k] = [] }
|
376
|
+
|
377
|
+
# Store keys by servers.
|
378
|
+
keys.each do |key|
|
379
|
+
keys_by_server[server(key)] << key
|
380
|
+
end
|
381
|
+
|
382
|
+
# Fetch and combine the results.
|
383
|
+
keys_by_server.each do |server, server_keys|
|
384
|
+
fetch_results.call(server, server_keys)
|
385
|
+
end
|
344
386
|
end
|
387
|
+
|
388
|
+
if backup
|
389
|
+
missing_keys = keys - results.keys
|
390
|
+
results.merge!(backup.get(missing_keys, opts)) if missing_keys.any?
|
391
|
+
end
|
392
|
+
results
|
345
393
|
end
|
346
|
-
|
394
|
+
|
347
395
|
def marshal(value, opts = {})
|
348
396
|
opts[:raw] ? value : Marshal.dump(value)
|
349
397
|
end
|
350
398
|
|
351
399
|
def unmarshal(value, key = nil)
|
352
400
|
return value if value.nil?
|
353
|
-
|
401
|
+
|
354
402
|
object = Marshal.load(value)
|
355
403
|
object.memcache_flags = value.memcache_flags
|
356
404
|
object.memcache_cas = value.memcache_cas
|
@@ -361,9 +409,9 @@ protected
|
|
361
409
|
end
|
362
410
|
|
363
411
|
def server(key)
|
364
|
-
|
365
|
-
return servers.first if servers.length == 1
|
412
|
+
return @server if @server
|
366
413
|
|
414
|
+
key = "#{namespace}:#{key}" if @hash_with_prefix
|
367
415
|
hash = (Zlib.crc32(key) >> 16) & 0x7fff
|
368
416
|
servers[hash % servers.length]
|
369
417
|
end
|
@@ -376,7 +424,7 @@ protected
|
|
376
424
|
@cache_by_scope[:default] = Memcache.new(:server => Memcache::LocalServer)
|
377
425
|
@fallback = :default
|
378
426
|
end
|
379
|
-
|
427
|
+
|
380
428
|
def include?(scope)
|
381
429
|
@cache_by_scope.include?(scope.to_sym)
|
382
430
|
end
|
@@ -388,7 +436,7 @@ protected
|
|
388
436
|
def [](scope)
|
389
437
|
@cache_by_scope[scope.to_sym] || @cache_by_scope[fallback]
|
390
438
|
end
|
391
|
-
|
439
|
+
|
392
440
|
def []=(scope, cache)
|
393
441
|
@cache_by_scope[scope.to_sym] = cache
|
394
442
|
end
|
@@ -397,7 +445,7 @@ protected
|
|
397
445
|
@cache_by_scope.values.each {|c| c.reset}
|
398
446
|
end
|
399
447
|
end
|
400
|
-
|
448
|
+
|
401
449
|
def self.pool
|
402
450
|
@@cache_pool ||= Pool.new
|
403
451
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'test/unit'
|
2
|
-
require File.dirname(__FILE__) + '/../lib/memcache/local_server'
|
3
2
|
require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
4
3
|
|
5
4
|
class MemcacheLocalServerTest < Test::Unit::TestCase
|
6
5
|
include MemcacheServerTestHelper
|
6
|
+
with_prefixes nil, "foo:", "bar:"
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@memcache = Memcache::LocalServer.new
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
3
|
+
|
4
|
+
class MemcacheNativeServerTest < Test::Unit::TestCase
|
5
|
+
include MemcacheServerTestHelper
|
6
|
+
include MemcacheServerTestHelper::AdvancedMethods
|
7
|
+
with_prefixes nil, "foo:", "bar:"
|
8
|
+
|
9
|
+
PORTS = [11212, 11213, 11214]
|
10
|
+
def setup
|
11
|
+
init_memcache(*PORTS) do
|
12
|
+
Memcache::NativeServer.new(:servers => PORTS.collect {|p| "localhost:#{p}"})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_server_down
|
17
|
+
m = Memcache::NativeServer.new(:servers => ["localhost:9998"])
|
18
|
+
|
19
|
+
assert_equal nil, m.get('foo')
|
20
|
+
assert_raise(Memcache::Error) do
|
21
|
+
m.set('foo', 'foo')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_close
|
26
|
+
m.close
|
27
|
+
|
28
|
+
m.set('foo', 'foo')
|
29
|
+
assert_equal 'foo', m.get('foo')
|
30
|
+
end
|
31
|
+
end
|
@@ -12,7 +12,7 @@ class MemcacheNullServerTest < Test::Unit::TestCase
|
|
12
12
|
|
13
13
|
def test_set_and_get
|
14
14
|
m.set(2, 'foo', 0)
|
15
|
-
|
15
|
+
|
16
16
|
assert_equal nil, m.get('2')
|
17
17
|
assert_equal nil, m.get('2')
|
18
18
|
end
|
@@ -34,32 +34,40 @@ class MemcacheNullServerTest < Test::Unit::TestCase
|
|
34
34
|
def test_multi_get
|
35
35
|
m.set(2, '1,2,3')
|
36
36
|
m.set(3, '4,5')
|
37
|
-
|
37
|
+
|
38
38
|
assert_equal Hash.new, m.get([2,3])
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def test_delete
|
42
42
|
m.set(2, '1,2,3')
|
43
|
-
|
43
|
+
|
44
44
|
assert_equal nil, m.get(2)
|
45
45
|
|
46
46
|
m.delete(2)
|
47
|
-
|
47
|
+
|
48
48
|
assert_equal nil, m.get(2)
|
49
49
|
end
|
50
50
|
|
51
51
|
def test_flush_all
|
52
52
|
m.set(2, 'bar')
|
53
|
-
|
53
|
+
|
54
54
|
assert_equal nil, m.get(2)
|
55
55
|
|
56
56
|
m.flush_all
|
57
|
-
|
57
|
+
|
58
58
|
assert_equal nil, m.get(2)
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def test_expiry
|
62
62
|
m.add('test', '1', 1)
|
63
63
|
assert_equal nil, m.get('test')
|
64
64
|
end
|
65
|
+
|
66
|
+
def test_prefix
|
67
|
+
assert_equal "foo", m.prefix = "foo"
|
68
|
+
assert_equal "foo", m.prefix
|
69
|
+
|
70
|
+
assert_equal nil, m.prefix = nil
|
71
|
+
assert_equal nil, m.prefix
|
72
|
+
end
|
65
73
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
3
|
+
|
4
|
+
$VERBOSE = nil
|
5
|
+
Memcache::Segmented.const_set('MAX_SIZE', 3)
|
6
|
+
|
7
|
+
class MemcacheSegmentedNativeServerTest < Test::Unit::TestCase
|
8
|
+
include MemcacheServerTestHelper
|
9
|
+
include MemcacheServerTestHelper::AdvancedMethods
|
10
|
+
with_prefixes nil, "foo:", "bar:"
|
11
|
+
|
12
|
+
PORTS = [11212, 11213, 11214]
|
13
|
+
def setup
|
14
|
+
init_memcache(*PORTS) do
|
15
|
+
Memcache::SegmentedNativeServer.new(:servers => PORTS.collect {|p| "localhost:#{p}"})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,20 +2,17 @@ require 'test/unit'
|
|
2
2
|
require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
3
3
|
|
4
4
|
$VERBOSE = nil
|
5
|
-
Memcache::
|
5
|
+
Memcache::Segmented.const_set('MAX_SIZE', 3)
|
6
6
|
|
7
7
|
class MemcacheSegmentedServerTest < Test::Unit::TestCase
|
8
8
|
include MemcacheServerTestHelper
|
9
9
|
include MemcacheServerTestHelper::AdvancedMethods
|
10
|
-
|
10
|
+
with_prefixes nil, "foo:", "bar:"
|
11
11
|
|
12
|
+
PORT = 11212
|
12
13
|
def setup
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def teardown
|
19
|
-
stop_memcache(PORT)
|
14
|
+
init_memcache(PORT) do
|
15
|
+
Memcache::SegmentedServer.new(:host => 'localhost', :port => PORT)
|
16
|
+
end
|
20
17
|
end
|
21
18
|
end
|
@@ -4,15 +4,13 @@ require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
|
4
4
|
class MemcacheServerTest < Test::Unit::TestCase
|
5
5
|
include MemcacheServerTestHelper
|
6
6
|
include MemcacheServerTestHelper::AdvancedMethods
|
7
|
-
|
7
|
+
with_prefixes nil, "foo:", "bar:"
|
8
8
|
|
9
|
+
PORT = 11212
|
9
10
|
def setup
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def teardown
|
15
|
-
stop_memcache(PORT)
|
11
|
+
init_memcache(PORT) do
|
12
|
+
Memcache::Server.new(:host => 'localhost', :port => PORT)
|
13
|
+
end
|
16
14
|
end
|
17
15
|
|
18
16
|
def test_stats
|
@@ -21,11 +19,11 @@ class MemcacheServerTest < Test::Unit::TestCase
|
|
21
19
|
m.get('bar')
|
22
20
|
|
23
21
|
stats = m.stats
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
assert stats['cmd_get'] > 0
|
23
|
+
assert stats['cmd_set'] > 0
|
24
|
+
assert stats['curr_items'] > 0
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
def test_clone
|
30
28
|
m.set('foo', 1)
|
31
29
|
c = m.clone
|