memcached-northscale 0.19.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,164 @@
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 = {
11
+ :logger => nil,
12
+ :string_return_types => false
13
+ }
14
+
15
+ attr_reader :logger
16
+
17
+ alias :servers= :set_servers
18
+
19
+ # See Memcached#new for details.
20
+ def initialize(*args)
21
+ opts = args.last.is_a?(Hash) ? args.pop : {}
22
+ servers = Array(
23
+ args.any? ? args.unshift : opts.delete(:servers)
24
+ ).flatten.compact
25
+
26
+ opts[:prefix_key] ||= opts[:namespace]
27
+ @logger = opts[:logger]
28
+ logger.info { "memcached #{VERSION} #{servers.inspect}" } if logger
29
+ super(servers, opts)
30
+ end
31
+
32
+ def servers
33
+ server_structs.map do |server|
34
+ Server.new server
35
+ end
36
+ end
37
+
38
+ def logger=(logger)
39
+ @logger = logger
40
+ end
41
+
42
+ # Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
43
+ # storing <tt>nil</tt> values.
44
+ def get(key, raw=false)
45
+ super(key, !raw)
46
+ rescue
47
+ end
48
+
49
+ # Alternative to #get. Accepts a key and an optional options hash supporting the single option
50
+ # :raw.
51
+ def read(key, options = {})
52
+ get(key, options[:raw])
53
+ end
54
+
55
+ # Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
56
+ def cas(key, ttl=@default_ttl, raw=false, &block)
57
+ super(key, ttl, !raw, &block)
58
+ true
59
+ rescue
60
+ false
61
+ end
62
+
63
+ alias :compare_and_swap :cas
64
+
65
+ # Wraps Memcached#get.
66
+ def get_multi(keys, raw=false)
67
+ get_orig(keys, !raw)
68
+ end
69
+
70
+ # Wraps Memcached#set.
71
+ def set(key, value, ttl=@default_ttl, raw=false)
72
+ super(key, value, ttl, !raw)
73
+ true
74
+ rescue
75
+ false
76
+ end
77
+
78
+ # Alternative to #set. Accepts a key, value, and an optional options hash supporting the
79
+ # options :raw and :ttl.
80
+ def write(key, value, options = {})
81
+ set(key, value, options[:ttl] || @default_ttl, options[:raw])
82
+ end
83
+
84
+ # Wraps Memcached#add so that it doesn't raise.
85
+ def add(key, value, ttl=@default_ttl, raw=false)
86
+ super(key, value, ttl, !raw)
87
+ # This causes me physical pain.
88
+ opts[:string_return_types] ? "STORED\r\n" : true
89
+ rescue NotStored # This can still throw exceptions. What's the right behavior if the
90
+ # server goes away?
91
+ opts[:string_return_types] ? "NOT STORED\r\n" : false
92
+ end
93
+
94
+ # Wraps Memcached#delete so that it doesn't raise.
95
+ def delete(key, expiry=0)
96
+ super(key)
97
+ rescue
98
+ end
99
+
100
+ # Wraps Memcached#incr so that it doesn't raise.
101
+ def incr(*args)
102
+ super
103
+ rescue
104
+ end
105
+
106
+ # Wraps Memcached#decr so that it doesn't raise.
107
+ def decr(*args)
108
+ super
109
+ rescue
110
+ end
111
+
112
+ # Wraps Memcached#append so that it doesn't raise.
113
+ def append(*args)
114
+ super
115
+ rescue
116
+ end
117
+
118
+ # Wraps Memcached#prepend so that it doesn't raise.
119
+ def prepend(*args)
120
+ super
121
+ rescue
122
+ end
123
+
124
+ alias :flush_all :flush
125
+
126
+ alias :"[]" :get
127
+ alias :"[]=" :set
128
+
129
+ end
130
+
131
+ class Server
132
+ def initialize(struct)
133
+ @struct = struct
134
+ end
135
+
136
+ def host
137
+ @struct.hostname
138
+ end
139
+
140
+ def port
141
+ @struct.port
142
+ end
143
+
144
+ def weight
145
+ @struct.weight
146
+ end
147
+
148
+ def multithreaded
149
+ true
150
+ end
151
+
152
+ def status
153
+ alive? ? 'CONNECTED' : 'NOT CONNECTED'
154
+ end
155
+
156
+ def inspect
157
+ "<Memcached::Rails::Server: %s:%d [%d] (%s)>" % [host, port, weight, status]
158
+ end
159
+
160
+ def alive?
161
+ @struct.fd != -1 || @struct.next_retry <= Time.now
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{memcached-northscale}
5
+ s.version = "0.19.5.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sean Lynch"]
9
+ s.date = %q{2010-06-02}
10
+ s.description = %q{Test gem. Do not use unless you know what you're doing.}
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.32.tar.gz", "ext/libmemcached.patch", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "ext/sasl.patch", "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.gemspec"]
15
+ s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/memcached/}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Memcached-northscale", "--main", "README"]
17
+ s.require_paths = ["lib", "ext"]
18
+ s.rubyforge_project = %q{northscale}
19
+ s.rubygems_version = %q{1.3.7}
20
+ s.summary = %q{Test gem. Do not use unless you know what you're doing.}
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::VERSION) >= 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,149 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/../setup"
3
+
4
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
5
+ require 'memcached'
6
+ require 'rubygems'
7
+
8
+ GC.copy_on_write_friendly = true if GC.respond_to?("copy_on_write_friendly=")
9
+
10
+ class Worker
11
+ def initialize(method_name, iterations)
12
+ @method = method_name || 'mixed'
13
+ @i = (iterations || 10000).to_i
14
+
15
+ puts "*** Running #{@method.inspect} test for #{@i} loops. ***"
16
+
17
+ @key1 = "key1-"*8
18
+ @key2 = "key2-"*8
19
+
20
+ @value = []
21
+ @marshalled = Marshal.dump(@value)
22
+
23
+ @opts = [
24
+ ["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
25
+ {
26
+ :buffer_requests => false,
27
+ :no_block => false,
28
+ :namespace => "namespace"
29
+ }
30
+ ]
31
+ @cache = Memcached.new(*@opts)
32
+
33
+ @cache.set @key1, @value
34
+ end
35
+
36
+ def work
37
+ case @method
38
+ when "set"
39
+ @i.times do
40
+ @cache.set @key1, @value
41
+ end
42
+ when "get"
43
+ @i.times do
44
+ @cache.get @key1
45
+ end
46
+ when "delete"
47
+ @i.times do
48
+ @cache.set @key1, @value
49
+ @cache.delete @key1
50
+ end
51
+ when "delete-miss"
52
+ @i.times do
53
+ @cache.delete @key1
54
+ end
55
+ when "get-miss"
56
+ @i.times do
57
+ begin
58
+ @cache.get @key2
59
+ rescue Memcached::NotFound
60
+ end
61
+ end
62
+ when "get-increasing"
63
+ one_k = "x"*1024
64
+ @i.times do |i|
65
+ @cache.set @key1, one_k*(i+1), 0, false
66
+ @cache.get @key1, false
67
+ end
68
+ when "get-miss-increasing"
69
+ @i.times do |i|
70
+ @cache.delete @key2 rescue nil
71
+ begin
72
+ @cache.get @key2
73
+ rescue Memcached::NotFound
74
+ end
75
+ end
76
+ when "add"
77
+ @i.times do
78
+ begin
79
+ @cache.delete @key1
80
+ rescue
81
+ end
82
+ @cache.add @key1, @value
83
+ end
84
+ when "add-present"
85
+ @cache.set @key1, @value
86
+ @i.times do
87
+ begin
88
+ @cache.add @key1, @value
89
+ rescue Memcached::NotStored
90
+ end
91
+ end
92
+ when "mixed"
93
+ @i.times do
94
+ @cache.set @key1, @value
95
+ @cache.get @key1
96
+ end
97
+ when "stats"
98
+ @i.times do
99
+ @cache.stats
100
+ end
101
+ when "multiget"
102
+ @i.times do
103
+ @cache.get([@key1, @key2])
104
+ end
105
+ when "clone"
106
+ @i.times do
107
+ cache = @cache.clone
108
+ end
109
+ when "reset"
110
+ @i.times do
111
+ @cache.reset
112
+ end
113
+ when "servers"
114
+ @i.times do
115
+ @cache.servers
116
+ end
117
+ when "server_by_key"
118
+ @i.times do
119
+ @cache.server_by_key(@key1)
120
+ end
121
+ else
122
+ raise "No such method"
123
+ end
124
+
125
+ puts "*** Garbage collect. ***"
126
+ 10.times do
127
+ GC.start
128
+ sleep 0.1
129
+ end
130
+
131
+ sts, server_sts, clients = 0, 0, 0
132
+ ObjectSpace.each_object(Memcached) { clients += 1 }
133
+ ObjectSpace.each_object(Rlibmemcached::MemcachedSt) { sts += 1 }
134
+ ObjectSpace.each_object(Rlibmemcached::MemcachedServerSt) { server_sts += 1 }
135
+ puts "*** Structs: #{sts} ***"
136
+ puts "*** Server structs: #{server_sts} ***"
137
+ puts "*** Clients: #{clients} ***"
138
+ end
139
+ end
140
+
141
+ Worker.new(ENV['METHOD'], ENV['LOOPS']).work
142
+
143
+ begin
144
+ require 'memory'
145
+ Process.memory.each do |key, value|
146
+ puts "#{key}: #{value/1024.0}M"
147
+ end
148
+ rescue LoadError
149
+ end