memcached-northscale 0.19.5.2

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.
@@ -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