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