memcached-uv 0.17.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/.gitignore +5 -0
- data/.gitmodules +3 -0
- data/BENCHMARKS +120 -0
- data/CHANGELOG +64 -0
- data/LICENSE +184 -0
- data/Manifest +27 -0
- data/README +111 -0
- data/Rakefile +46 -0
- data/TODO +4 -0
- data/ext/extconf.rb +67 -0
- data/ext/libmemcached-0.32.tar.gz +0 -0
- data/ext/libmemcached.patch +270 -0
- data/ext/rlibmemcached.i +212 -0
- data/ext/rlibmemcached_wrap.c +13090 -0
- data/lib/memcached/behaviors.rb +78 -0
- data/lib/memcached/exceptions.rb +84 -0
- data/lib/memcached/integer.rb +6 -0
- data/lib/memcached/memcached.rb +496 -0
- data/lib/memcached/rails.rb +121 -0
- data/lib/memcached.rb +31 -0
- data/test/profile/benchmark.rb +210 -0
- data/test/profile/profile.rb +14 -0
- data/test/profile/valgrind.rb +147 -0
- data/test/setup.rb +29 -0
- data/test/teardown.rb +0 -0
- data/test/test_helper.rb +18 -0
- data/test/unit/binding_test.rb +8 -0
- data/test/unit/memcached_test.rb +1029 -0
- data/test/unit/rails_test.rb +102 -0
- metadata +93 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
class Memcached
|
2
|
+
|
3
|
+
(instance_methods - NilClass.instance_methods).each do |method_name|
|
4
|
+
eval("alias :'#{method_name}_orig' :'#{method_name}'")
|
5
|
+
end
|
6
|
+
|
7
|
+
# A legacy compatibility wrapper for the Memcached class. It has basic compatibility with the <b>memcache-client</b> API.
|
8
|
+
class Rails < ::Memcached
|
9
|
+
|
10
|
+
DEFAULTS[:logger] = nil
|
11
|
+
|
12
|
+
attr_reader :logger
|
13
|
+
|
14
|
+
alias :servers= :set_servers
|
15
|
+
|
16
|
+
# See Memcached#new for details.
|
17
|
+
def initialize(*args)
|
18
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
19
|
+
servers = Array(
|
20
|
+
args.any? ? args.unshift : opts.delete(:servers)
|
21
|
+
).flatten.compact
|
22
|
+
|
23
|
+
opts[:prefix_key] ||= opts[:namespace]
|
24
|
+
@logger = opts[:logger]
|
25
|
+
logger.info { "memcached #{VERSION} #{servers.inspect}" } if logger
|
26
|
+
super(servers, opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger=(logger)
|
30
|
+
@logger = logger
|
31
|
+
end
|
32
|
+
|
33
|
+
# Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
|
34
|
+
# storing <tt>nil</tt> values.
|
35
|
+
def get(key, raw=false)
|
36
|
+
super(key, !raw)
|
37
|
+
rescue NotFound
|
38
|
+
end
|
39
|
+
|
40
|
+
def read(key, options)
|
41
|
+
raw = false
|
42
|
+
raw = options[:raw] if options.has_key?(:raw)
|
43
|
+
self.get(key, raw)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
|
47
|
+
def cas(key, ttl=@default_ttl, raw=false, &block)
|
48
|
+
super(key, ttl, !raw, &block)
|
49
|
+
rescue NotFound
|
50
|
+
end
|
51
|
+
|
52
|
+
alias :compare_and_swap :cas
|
53
|
+
|
54
|
+
# Wraps Memcached#get.
|
55
|
+
def get_multi(keys, raw=false)
|
56
|
+
get_orig(keys, !raw)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Wraps Memcached#set.
|
60
|
+
def set(key, value, ttl=@default_ttl, raw=false)
|
61
|
+
super(key, value, ttl, !raw)
|
62
|
+
end
|
63
|
+
|
64
|
+
def write(key, value, options)
|
65
|
+
ttl = @default_ttl
|
66
|
+
ttl = options[:ttl] if options.has_key?(:ttl)
|
67
|
+
raw = false
|
68
|
+
raw = options[:raw] if options.has_key?(:raw)
|
69
|
+
self.set(key, value, ttl=ttl, raw=raw)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Wraps Memcached#add so that it doesn't raise.
|
73
|
+
def add(key, value, ttl=@default_ttl, raw=false)
|
74
|
+
super(key, value, ttl, !raw)
|
75
|
+
true
|
76
|
+
rescue NotStored
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
# Wraps Memcached#delete so that it doesn't raise.
|
81
|
+
def delete(key)
|
82
|
+
super
|
83
|
+
rescue NotFound
|
84
|
+
end
|
85
|
+
|
86
|
+
# Wraps Memcached#incr so that it doesn't raise.
|
87
|
+
def incr(*args)
|
88
|
+
super
|
89
|
+
rescue NotFound
|
90
|
+
end
|
91
|
+
|
92
|
+
# Wraps Memcached#decr so that it doesn't raise.
|
93
|
+
def decr(*args)
|
94
|
+
super
|
95
|
+
rescue NotFound
|
96
|
+
end
|
97
|
+
|
98
|
+
# Wraps Memcached#append so that it doesn't raise.
|
99
|
+
def append(*args)
|
100
|
+
super
|
101
|
+
rescue NotStored
|
102
|
+
end
|
103
|
+
|
104
|
+
# Wraps Memcached#prepend so that it doesn't raise.
|
105
|
+
def prepend(*args)
|
106
|
+
super
|
107
|
+
rescue NotStored
|
108
|
+
end
|
109
|
+
|
110
|
+
# Namespace accessor.
|
111
|
+
def namespace
|
112
|
+
options[:prefix_key]
|
113
|
+
end
|
114
|
+
|
115
|
+
alias :flush_all :flush
|
116
|
+
|
117
|
+
alias :"[]" :get
|
118
|
+
alias :"[]=" :set
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
data/lib/memcached.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
=begin rdoc
|
3
|
+
The generated SWIG module for accessing libmemcached's C API.
|
4
|
+
|
5
|
+
Includes the full set of libmemcached static methods (as defined in <tt>$INCLUDE_PATH/libmemcached/memcached.h</tt>), and classes for the available structs:
|
6
|
+
|
7
|
+
* <b>Rlibmemcached::MemcachedResultSt</b>
|
8
|
+
* <b>Rlibmemcached::MemcachedServerSt</b>
|
9
|
+
* <b>Rlibmemcached::MemcachedSt</b>
|
10
|
+
* <b>Rlibmemcached::MemcachedStatSt</b>
|
11
|
+
* <b>Rlibmemcached::MemcachedStringSt</b>
|
12
|
+
|
13
|
+
A number of SWIG typemaps and C helper methods are also defined in <tt>ext/libmemcached.i</tt>.
|
14
|
+
|
15
|
+
=end
|
16
|
+
module Rlibmemcached
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rlibmemcached'
|
20
|
+
|
21
|
+
class Memcached
|
22
|
+
Lib = Rlibmemcached
|
23
|
+
raise "libmemcached 0.32 required; you somehow linked to #{Lib.memcached_lib_version}." unless "0.32" == Lib.memcached_lib_version
|
24
|
+
VERSION = File.read("#{File.dirname(__FILE__)}/../CHANGELOG")[/v([\d\.]+)\./, 1]
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'memcached/integer'
|
28
|
+
require 'memcached/exceptions'
|
29
|
+
require 'memcached/behaviors'
|
30
|
+
require 'memcached/memcached'
|
31
|
+
require 'memcached/rails'
|
@@ -0,0 +1,210 @@
|
|
1
|
+
|
2
|
+
HERE = File.dirname(__FILE__)
|
3
|
+
$LOAD_PATH << "#{HERE}/../../lib/"
|
4
|
+
UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
|
5
|
+
|
6
|
+
require 'memcached'
|
7
|
+
require 'benchmark'
|
8
|
+
require 'rubygems'
|
9
|
+
require 'ruby-debug' if ENV['DEBUG']
|
10
|
+
begin; require 'memory'; rescue LoadError; end
|
11
|
+
|
12
|
+
puts `uname -a`
|
13
|
+
puts "Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
|
14
|
+
|
15
|
+
[ ["memcached", "memcached"],
|
16
|
+
["binary42-remix-stash", "remix/stash"],
|
17
|
+
# ["astro-remcached", "remcached"], # Clobbers the "Memcached" constant
|
18
|
+
["memcache-client", "memcache"]].each do |gem_name, requirement|
|
19
|
+
require requirement
|
20
|
+
gem gem_name
|
21
|
+
puts "Loaded #{gem_name} #{Gem.loaded_specs[gem_name].version.to_s rescue nil}"
|
22
|
+
end
|
23
|
+
|
24
|
+
class Remix::Stash
|
25
|
+
# Remix::Stash API doesn't let you set servers
|
26
|
+
@@clusters = {:default => Remix::Stash::Cluster.new(['127.0.0.1:43042', '127.0.0.1:43043'])}
|
27
|
+
end
|
28
|
+
|
29
|
+
class Bench
|
30
|
+
|
31
|
+
def initialize(loops = nil, stack_depth = nil)
|
32
|
+
@loops = (loops || 20000).to_i
|
33
|
+
@stack_depth = (stack_depth || 0).to_i
|
34
|
+
|
35
|
+
puts "Loops is #{@loops}"
|
36
|
+
puts "Stack depth is #{@stack_depth}"
|
37
|
+
|
38
|
+
@m_value = Marshal.dump(
|
39
|
+
@small_value = ["testing"])
|
40
|
+
@m_large_value = Marshal.dump(
|
41
|
+
@large_value = [{"test" => "1", "test2" => "2", Object.new => "3", 4 => 4, "test5" => 2**65}] * 2048)
|
42
|
+
|
43
|
+
puts "Small value size is: #{@m_value.size} bytes"
|
44
|
+
puts "Large value size is: #{@m_large_value.size} bytes"
|
45
|
+
|
46
|
+
@keys = [
|
47
|
+
@k1 = "Short",
|
48
|
+
@k2 = "Sym1-2-3::45" * 8,
|
49
|
+
@k3 = "Long" * 40,
|
50
|
+
@k4 = "Medium" * 8,
|
51
|
+
@k5 = "Medium2" * 8,
|
52
|
+
@k6 = "Long3" * 40]
|
53
|
+
|
54
|
+
reset_servers
|
55
|
+
reset_clients
|
56
|
+
|
57
|
+
Benchmark.bm(36) do |x|
|
58
|
+
@benchmark = x
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def run(level = @stack_depth)
|
63
|
+
level > 0 ? run(level - 1) : run_without_recursion
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def reset_servers
|
69
|
+
system("ruby #{HERE}/../setup.rb")
|
70
|
+
sleep(1)
|
71
|
+
end
|
72
|
+
|
73
|
+
def reset_clients
|
74
|
+
@clients = {
|
75
|
+
"libm" => Memcached::Rails.new(
|
76
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
77
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace"),
|
78
|
+
"libm:noblock" => Memcached::Rails.new(
|
79
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
80
|
+
:no_block => true, :buffer_requests => true, :namespace => "namespace"),
|
81
|
+
"libm:udp" => Memcached::Rails.new(
|
82
|
+
["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
|
83
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace"),
|
84
|
+
"libm:binary" => Memcached::Rails.new(
|
85
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
86
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace", :binary_protocol => true),
|
87
|
+
"libm:noblock_binary" => Memcached::Rails.new(
|
88
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
89
|
+
:no_block => true, :buffer_requests => true, :namespace => "namespace", :binary_protocol => true),
|
90
|
+
"ruby" => MemCache.new(['127.0.0.1:43042', '127.0.0.1:43043'], :namespace => "namespace"),
|
91
|
+
"stash" => Remix::Stash.new(:root)}
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def benchmark_clients(test_name, clients = @clients)
|
96
|
+
clients.keys.sort.each do |client_name|
|
97
|
+
next if client_name == "stash" and test_name == "set-large" # Don't let stash break the world
|
98
|
+
client = clients[client_name]
|
99
|
+
begin
|
100
|
+
yield client
|
101
|
+
@benchmark.report("#{test_name}:#{client_name}") { @loops.times { yield client } }
|
102
|
+
rescue => e
|
103
|
+
# puts "#{test_name}:#{client_name} => #{e.class}"
|
104
|
+
# reset_clients
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def benchmark_hashes(hashes, test_name)
|
110
|
+
hashes.each do |hash_name, int|
|
111
|
+
@m = Memcached::Rails.new(:hash => hash_name)
|
112
|
+
@benchmark.report("#{test_name}:#{hash_name}") do
|
113
|
+
@loops.times { yield int }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_without_recursion
|
119
|
+
benchmark_clients("set") do |c|
|
120
|
+
c.set @k1, @m_value, 0, true
|
121
|
+
c.set @k2, @m_value, 0, true
|
122
|
+
c.set @k3, @m_value, 0, true
|
123
|
+
end
|
124
|
+
|
125
|
+
benchmark_clients("get") do |c|
|
126
|
+
c.get @k1, true
|
127
|
+
c.get @k2, true
|
128
|
+
c.get @k3, true
|
129
|
+
end
|
130
|
+
|
131
|
+
benchmark_clients("get-multi") do |c|
|
132
|
+
c.get_multi @keys, true
|
133
|
+
end
|
134
|
+
|
135
|
+
benchmark_clients("append") do |c|
|
136
|
+
c.append @k1, @m_value
|
137
|
+
c.append @k2, @m_value
|
138
|
+
c.append @k3, @m_value
|
139
|
+
end
|
140
|
+
|
141
|
+
benchmark_clients("delete") do |c|
|
142
|
+
c.delete @k1
|
143
|
+
c.delete @k2
|
144
|
+
c.delete @k3
|
145
|
+
end
|
146
|
+
|
147
|
+
benchmark_clients("get-missing") do |c|
|
148
|
+
c.get @k1
|
149
|
+
c.get @k2
|
150
|
+
c.get @k3
|
151
|
+
end
|
152
|
+
|
153
|
+
benchmark_clients("append-missing") do |c|
|
154
|
+
c.append @k1, @m_value
|
155
|
+
c.append @k2, @m_value
|
156
|
+
c.append @k3, @m_value
|
157
|
+
end
|
158
|
+
|
159
|
+
benchmark_clients("set-large") do |c|
|
160
|
+
c.set @k1, @m_large_value, 0, true
|
161
|
+
c.set @k2, @m_large_value, 0, true
|
162
|
+
c.set @k3, @m_large_value, 0, true
|
163
|
+
end
|
164
|
+
|
165
|
+
benchmark_clients("get-large") do |c|
|
166
|
+
c.get @k1, true
|
167
|
+
c.get @k2, true
|
168
|
+
c.get @k3, true
|
169
|
+
end
|
170
|
+
|
171
|
+
benchmark_clients("set-ruby") do |c|
|
172
|
+
c.set @k1, @value
|
173
|
+
c.set @k2, @value
|
174
|
+
c.set @k3, @value
|
175
|
+
end
|
176
|
+
|
177
|
+
benchmark_clients("get-ruby") do |c|
|
178
|
+
c.get @k1
|
179
|
+
c.get @k2
|
180
|
+
c.get @k3
|
181
|
+
end
|
182
|
+
|
183
|
+
benchmark_clients("set-ruby-large") do |c|
|
184
|
+
c.set @k1, @large_value
|
185
|
+
c.set @k2, @large_value
|
186
|
+
c.set @k3, @large_value
|
187
|
+
end
|
188
|
+
|
189
|
+
benchmark_clients("get-ruby-large") do |c|
|
190
|
+
c.get @k1
|
191
|
+
c.get @k2
|
192
|
+
c.get @k3
|
193
|
+
end
|
194
|
+
|
195
|
+
benchmark_hashes(Memcached::HASH_VALUES, "hash") do |i|
|
196
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k1, i)
|
197
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k2, i)
|
198
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k3, i)
|
199
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k4, i)
|
200
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k5, i)
|
201
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k6, i)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
Bench.new(ENV["LOOPS"], ENV["STACK_DEPTH"]).run
|
207
|
+
|
208
|
+
Process.memory.each do |key, value|
|
209
|
+
puts "#{key}: #{value/1024.0}M"
|
210
|
+
end if Process.respond_to? :memory
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
require "#{File.dirname(__FILE__)}/../setup"
|
3
|
+
|
4
|
+
$LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
|
5
|
+
require 'rubygems'
|
6
|
+
require 'memcached'
|
7
|
+
require 'ruby-prof'
|
8
|
+
|
9
|
+
result = RubyProf.profile do
|
10
|
+
load "#{HERE}/profile/valgrind.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
printer = RubyProf::GraphPrinter.new(result)
|
14
|
+
printer.print(STDOUT, 0)
|
@@ -0,0 +1,147 @@
|
|
1
|
+
|
2
|
+
require "#{File.dirname(__FILE__)}/../setup"
|
3
|
+
|
4
|
+
$LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
|
5
|
+
require 'memcached'
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
class Worker
|
9
|
+
def initialize(method_name, iterations)
|
10
|
+
@method = method_name || 'mixed'
|
11
|
+
@i = (iterations || 10000).to_i
|
12
|
+
|
13
|
+
puts "*** Running #{@method.inspect} test for #{@i} loops. ***"
|
14
|
+
|
15
|
+
@key1 = "key1-"*8
|
16
|
+
@key2 = "key2-"*8
|
17
|
+
|
18
|
+
@value = []
|
19
|
+
@marshalled = Marshal.dump(@value)
|
20
|
+
|
21
|
+
@opts = [
|
22
|
+
["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
|
23
|
+
{
|
24
|
+
:buffer_requests => false,
|
25
|
+
:no_block => false,
|
26
|
+
:namespace => "namespace"
|
27
|
+
}
|
28
|
+
]
|
29
|
+
@cache = Memcached.new(*@opts)
|
30
|
+
|
31
|
+
@cache.set @key1, @value
|
32
|
+
end
|
33
|
+
|
34
|
+
def work
|
35
|
+
case @method
|
36
|
+
when "set"
|
37
|
+
@i.times do
|
38
|
+
@cache.set @key1, @value
|
39
|
+
end
|
40
|
+
when "get"
|
41
|
+
@i.times do
|
42
|
+
@cache.get @key1
|
43
|
+
end
|
44
|
+
when "delete"
|
45
|
+
@i.times do
|
46
|
+
@cache.set @key1, @value
|
47
|
+
@cache.delete @key1
|
48
|
+
end
|
49
|
+
when "delete-miss"
|
50
|
+
@i.times do
|
51
|
+
@cache.delete @key1
|
52
|
+
end
|
53
|
+
when "get-miss"
|
54
|
+
@i.times do
|
55
|
+
begin
|
56
|
+
@cache.get @key2
|
57
|
+
rescue Memcached::NotFound
|
58
|
+
end
|
59
|
+
end
|
60
|
+
when "get-increasing"
|
61
|
+
one_k = "x"*1024
|
62
|
+
@i.times do |i|
|
63
|
+
@cache.set @key1, one_k*(i+1), 0, false
|
64
|
+
@cache.get @key1, false
|
65
|
+
end
|
66
|
+
when "get-miss-increasing"
|
67
|
+
@i.times do |i|
|
68
|
+
@cache.delete @key2 rescue nil
|
69
|
+
begin
|
70
|
+
@cache.get @key2
|
71
|
+
rescue Memcached::NotFound
|
72
|
+
end
|
73
|
+
end
|
74
|
+
when "add"
|
75
|
+
@i.times do
|
76
|
+
begin
|
77
|
+
@cache.delete @key1
|
78
|
+
rescue
|
79
|
+
end
|
80
|
+
@cache.add @key1, @value
|
81
|
+
end
|
82
|
+
when "add-present"
|
83
|
+
@cache.set @key1, @value
|
84
|
+
@i.times do
|
85
|
+
begin
|
86
|
+
@cache.add @key1, @value
|
87
|
+
rescue Memcached::NotStored
|
88
|
+
end
|
89
|
+
end
|
90
|
+
when "mixed"
|
91
|
+
@i.times do
|
92
|
+
@cache.set @key1, @value
|
93
|
+
@cache.get @key1
|
94
|
+
end
|
95
|
+
when "stats"
|
96
|
+
@i.times do
|
97
|
+
@cache.stats
|
98
|
+
end
|
99
|
+
when "multiget"
|
100
|
+
@i.times do
|
101
|
+
@cache.get([@key1, @key2])
|
102
|
+
end
|
103
|
+
when "clone"
|
104
|
+
@i.times do
|
105
|
+
cache = @cache.clone
|
106
|
+
end
|
107
|
+
when "reset"
|
108
|
+
@i.times do
|
109
|
+
@cache.reset
|
110
|
+
end
|
111
|
+
when "servers"
|
112
|
+
@i.times do
|
113
|
+
@cache.servers
|
114
|
+
end
|
115
|
+
when "server_by_key"
|
116
|
+
@i.times do
|
117
|
+
@cache.server_by_key(@key1)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
raise "No such method"
|
121
|
+
end
|
122
|
+
|
123
|
+
puts "*** Garbage collect. ***"
|
124
|
+
10.times do
|
125
|
+
GC.start
|
126
|
+
sleep 0.1
|
127
|
+
end
|
128
|
+
|
129
|
+
sts, server_sts, clients = 0, 0, 0
|
130
|
+
ObjectSpace.each_object(Memcached) { clients += 1 }
|
131
|
+
ObjectSpace.each_object(Rlibmemcached::MemcachedSt) { sts += 1 }
|
132
|
+
ObjectSpace.each_object(Rlibmemcached::MemcachedServerSt) { server_sts += 1 }
|
133
|
+
puts "*** Structs: #{sts} ***"
|
134
|
+
puts "*** Server structs: #{server_sts} ***"
|
135
|
+
puts "*** Clients: #{clients} ***"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
Worker.new(ENV['METHOD'], ENV['LOOPS']).work
|
140
|
+
|
141
|
+
begin
|
142
|
+
require 'memory'
|
143
|
+
Process.memory.each do |key, value|
|
144
|
+
puts "#{key}: #{value/1024.0}M"
|
145
|
+
end
|
146
|
+
rescue LoadError
|
147
|
+
end
|
data/test/setup.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
unless defined? UNIX_SOCKET_NAME
|
3
|
+
HERE = File.dirname(__FILE__)
|
4
|
+
UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
|
5
|
+
|
6
|
+
# Kill memcached
|
7
|
+
system("killall -9 memcached")
|
8
|
+
|
9
|
+
# Start memcached
|
10
|
+
verbosity = (ENV['DEBUG'] ? "-vv" : "")
|
11
|
+
log = "/tmp/memcached.log"
|
12
|
+
system ">#{log}"
|
13
|
+
|
14
|
+
# TCP memcached
|
15
|
+
(43042..43046).each do |port|
|
16
|
+
cmd = "memcached #{verbosity} -U 0 -p #{port} >> #{log} 2>&1 &"
|
17
|
+
raise "'#{cmd}' failed to start" unless system(cmd)
|
18
|
+
end
|
19
|
+
# UDP memcached
|
20
|
+
(43052..43053).each do |port|
|
21
|
+
cmd = "memcached #{verbosity} -U #{port} -p 0 >> #{log} 2>&1 &"
|
22
|
+
raise "'#{cmd}' failed to start" unless system(cmd)
|
23
|
+
end
|
24
|
+
# Domain socket memcached
|
25
|
+
(0..1).each do |i|
|
26
|
+
cmd = "memcached -M -s #{UNIX_SOCKET_NAME}#{i} #{verbosity} >> #{log} 2>&1 &"
|
27
|
+
raise "'#{cmd}' failed to start" unless system(cmd)
|
28
|
+
end
|
29
|
+
end
|
data/test/teardown.rb
ADDED
File without changes
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
$LOAD_PATH << "#{File.dirname(__FILE__)}/../lib"
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mocha'
|
6
|
+
|
7
|
+
if ENV['DEBUG']
|
8
|
+
require 'ruby-debug'
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'memcached'
|
12
|
+
require 'test/unit'
|
13
|
+
require 'ostruct'
|
14
|
+
|
15
|
+
UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached') unless defined? UNIX_SOCKET_NAME
|
16
|
+
|
17
|
+
class GenericClass
|
18
|
+
end
|