memcached-northscale-heroku 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/BENCHMARKS +120 -0
- data/CHANGELOG +64 -0
- data/LICENSE +184 -0
- data/Manifest +27 -0
- data/README +111 -0
- data/Rakefile +31 -0
- data/TODO +4 -0
- data/ext/extconf.rb +64 -0
- data/ext/libmemcached-0.35+sasl.tar.gz +0 -0
- data/ext/rlibmemcached.i +221 -0
- data/ext/rlibmemcached_wrap.c +13694 -0
- data/lib/memcached.rb +32 -0
- data/lib/memcached/auth.rb +17 -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 +523 -0
- data/lib/memcached/rails.rb +97 -0
- data/memcached-northscale-heroku.gemspec +32 -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 +100 -0
@@ -0,0 +1,97 @@
|
|
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
|
+
alias :servers= :set_servers
|
11
|
+
|
12
|
+
# See Memcached#new for details.
|
13
|
+
def initialize(*args)
|
14
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
15
|
+
servers = Array(
|
16
|
+
args.any? ? args.unshift : opts.delete(:servers)
|
17
|
+
).flatten.compact
|
18
|
+
|
19
|
+
opts[:prefix_key] ||= opts[:namespace]
|
20
|
+
super(servers, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
|
24
|
+
# storing <tt>nil</tt> values.
|
25
|
+
def get(key, raw=false)
|
26
|
+
super(key, !raw)
|
27
|
+
rescue NotFound
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
|
31
|
+
def cas(key, ttl=@default_ttl, raw=false, &block)
|
32
|
+
super(key, ttl, !raw, &block)
|
33
|
+
rescue NotFound
|
34
|
+
end
|
35
|
+
|
36
|
+
alias :compare_and_swap :cas
|
37
|
+
|
38
|
+
# Wraps Memcached#get.
|
39
|
+
def get_multi(keys, raw=false)
|
40
|
+
get_orig(keys, !raw)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Wraps Memcached#set.
|
44
|
+
def set(key, value, ttl=@default_ttl, raw=false)
|
45
|
+
super(key, value, ttl, !raw)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Wraps Memcached#add so that it doesn't raise.
|
49
|
+
def add(key, value, ttl=@default_ttl, raw=false)
|
50
|
+
super(key, value, ttl, !raw)
|
51
|
+
true
|
52
|
+
rescue NotStored
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
# Wraps Memcached#delete so that it doesn't raise.
|
57
|
+
def delete(key)
|
58
|
+
super
|
59
|
+
rescue NotFound
|
60
|
+
end
|
61
|
+
|
62
|
+
# Wraps Memcached#incr so that it doesn't raise.
|
63
|
+
def incr(*args)
|
64
|
+
super
|
65
|
+
rescue NotFound
|
66
|
+
end
|
67
|
+
|
68
|
+
# Wraps Memcached#decr so that it doesn't raise.
|
69
|
+
def decr(*args)
|
70
|
+
super
|
71
|
+
rescue NotFound
|
72
|
+
end
|
73
|
+
|
74
|
+
# Wraps Memcached#append so that it doesn't raise.
|
75
|
+
def append(*args)
|
76
|
+
super
|
77
|
+
rescue NotStored
|
78
|
+
end
|
79
|
+
|
80
|
+
# Wraps Memcached#prepend so that it doesn't raise.
|
81
|
+
def prepend(*args)
|
82
|
+
super
|
83
|
+
rescue NotStored
|
84
|
+
end
|
85
|
+
|
86
|
+
# Namespace accessor.
|
87
|
+
def namespace
|
88
|
+
options[:prefix_key]
|
89
|
+
end
|
90
|
+
|
91
|
+
alias :flush_all :flush
|
92
|
+
|
93
|
+
alias :"[]" :get
|
94
|
+
alias :"[]=" :set
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{memcached-northscale-heroku}
|
5
|
+
s.version = "0.17.7"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Evan Weaver - updated by NorthScale for Heroku"]
|
9
|
+
s.date = %q{2009-12-16}
|
10
|
+
s.description = %q{An interface to the libmemcached C client + sasl auth support.}
|
11
|
+
s.email = %q{}
|
12
|
+
s.extensions = ["ext/extconf.rb"]
|
13
|
+
s.extra_rdoc_files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "README", "TODO", "lib/memcached.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb"]
|
14
|
+
s.files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "ext/extconf.rb", "ext/libmemcached-0.35+sasl.tar.gz", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "lib/memcached.rb", "lib/memcached/auth.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "test/profile/benchmark.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "memcached-northscale-heroku.gemspec"]
|
15
|
+
s.homepage = %q{http://github.com/seanlynch/libmemcached-ruby}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Memcached-northscale-heroku", "--main", "README"]
|
17
|
+
s.require_paths = ["lib", "ext"]
|
18
|
+
s.rubyforge_project = %q{NorthScale-Heroku}
|
19
|
+
s.rubygems_version = %q{1.3.5}
|
20
|
+
s.summary = %q{An interface to the libmemcached C client + sasl auth support.}
|
21
|
+
s.test_files = ["test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
@@ -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
|