memcached 1.0.7 → 1.1

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.
@@ -24,7 +24,6 @@ class Memcached
24
24
  VERSION = File.read("#{File.dirname(__FILE__)}/../CHANGELOG")[/v([\d\.]+)\./, 1]
25
25
  end
26
26
 
27
- require 'memcached/integer'
28
27
  require 'memcached/exceptions'
29
28
  require 'memcached/behaviors'
30
29
  require 'memcached/auth'
@@ -91,7 +91,7 @@ Valid option parameters are:
91
91
  <tt>:default_weight</tt>:: The weight to use if <tt>:ketama_weighted</tt> is <tt>true</tt>, but no weight is specified for a server.
92
92
  <tt>:hash_with_prefix_key</tt>:: Whether to include the prefix when calculating which server a key falls on. Defaults to <tt>true</tt>.
93
93
  <tt>:use_udp</tt>:: Use the UDP protocol to reduce connection overhead. Defaults to false.
94
- <tt>:binary_protocol</tt>:: Use the binary protocol to reduce query processing overhead. Defaults to false.
94
+ <tt>:binary_protocol</tt>:: Use the binary protocol. Defaults to false. Please note that using the binary protocol is usually <b>slower</b> than the ASCII protocol.
95
95
  <tt>:sort_hosts</tt>:: Whether to force the server list to stay sorted. This defeats consistent hashing and is rarely useful.
96
96
  <tt>:verify_key</tt>:: Validate keys before accepting them. Never disable this.
97
97
 
@@ -120,7 +120,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
120
120
  end
121
121
 
122
122
  instance_eval { send(:extend, Experimental) } if options[:experimental_features]
123
-
123
+
124
124
  options[:binary_protocol] = true if options[:credentials] != nil
125
125
 
126
126
  # Force :buffer_requests to use :no_block
@@ -303,7 +303,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
303
303
 
304
304
  # Set a key/value pair. Accepts a String <tt>key</tt> and an arbitrary Ruby object. Overwrites any existing value on the server.
305
305
  #
306
- # Accepts an optional <tt>ttl</tt> value to specify the maximum lifetime of the key on the server. <tt>ttl</tt> can be either an integer number of seconds, or a Time elapsed time object. <tt>0</tt> means no ttl. Note that there is no guarantee that the key will persist as long as the <tt>ttl</tt>, but it will not persist longer.
306
+ # Accepts an optional <tt>ttl</tt> value to specify the maximum lifetime of the key on the server, in seconds. <tt>ttl</tt> must be a <tt>FixNum</tt>. <tt>0</tt> means no ttl. Note that there is no guarantee that the key will persist as long as the <tt>ttl</tt>, but it will not persist longer.
307
307
  #
308
308
  # Also accepts a <tt>marshal</tt> value, which defaults to <tt>true</tt>. Set <tt>marshal</tt> to <tt>false</tt> if you want the <tt>value</tt> to be set directly.
309
309
  #
@@ -319,7 +319,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
319
319
  retry if e.instance_of?(ClientError) && !tries
320
320
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
321
321
  tries += 1
322
- retry
322
+ retry
323
323
  end
324
324
  end
325
325
 
@@ -335,7 +335,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
335
335
  tries ||= 0
336
336
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
337
337
  tries += 1
338
- retry
338
+ retry
339
339
  end
340
340
  end
341
341
 
@@ -352,7 +352,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
352
352
  tries ||= 0
353
353
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
354
354
  tries += 1
355
- retry
355
+ retry
356
356
  end
357
357
 
358
358
  # Decrement a key's value. The parameters and exception behavior are the same as <tt>increment</tt>.
@@ -364,7 +364,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
364
364
  tries ||= 0
365
365
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
366
366
  tries += 1
367
- retry
367
+ retry
368
368
  end
369
369
 
370
370
  #:stopdoc:
@@ -384,7 +384,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
384
384
  tries ||= 0
385
385
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
386
386
  tries += 1
387
- retry
387
+ retry
388
388
  end
389
389
  end
390
390
 
@@ -401,7 +401,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
401
401
  tries ||= 0
402
402
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
403
403
  tries += 1
404
- retry
404
+ retry
405
405
  end
406
406
 
407
407
  # Prepends a string to a key's value. The parameters and exception behavior are the same as <tt>append</tt>.
@@ -415,7 +415,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
415
415
  tries ||= 0
416
416
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
417
417
  tries += 1
418
- retry
418
+ retry
419
419
  end
420
420
 
421
421
  # Reads a key's value from the server and yields it to a block. Replaces the key's value with the result of the block as long as the key hasn't been updated in the meantime, otherwise raises <b>Memcached::NotStored</b>. Accepts a String <tt>key</tt> and a block.
@@ -434,9 +434,9 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
434
434
  tries_for_get ||= 0
435
435
  raise unless tries_for_get < options[:exception_retry_limit] && should_retry(e)
436
436
  tries_for_get += 1
437
- retry
437
+ retry
438
438
  end
439
-
439
+
440
440
  cas = @struct.result.cas
441
441
 
442
442
  value = Marshal.load(value) if marshal
@@ -452,7 +452,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
452
452
  tries_for_cas ||= 0
453
453
  raise unless tries_for_cas < options[:exception_retry_limit] && should_retry(e)
454
454
  tries_for_cas += 1
455
- retry
455
+ retry
456
456
  end
457
457
  end
458
458
 
@@ -470,7 +470,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
470
470
  tries ||= 0
471
471
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
472
472
  tries += 1
473
- retry
473
+ retry
474
474
  end
475
475
 
476
476
  # Flushes all key/value pairs from all the servers.
@@ -482,7 +482,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
482
482
  tries ||= 0
483
483
  raise unless tries < options[:exception_retry_limit] && should_retry(e)
484
484
  tries += 1
485
- retry
485
+ retry
486
486
  end
487
487
 
488
488
  ### Getters
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{memcached}
5
- s.version = "1.0.7"
5
+ s.version = "1.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Weaver"]
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.email = %q{}
13
13
  s.extensions = ["ext/extconf.rb"]
14
14
  s.extra_rdoc_files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "README", "TODO", "lib/memcached.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/experimental.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb"]
15
- s.files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "ext/extconf.rb", "ext/libmemcached-0.32.tar.gz", "ext/libmemcached-2.patch", "ext/libmemcached-3.patch", "ext/libmemcached-4.patch", "ext/libmemcached-5.patch", "ext/libmemcached-6.patch", "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/experimental.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "memcached.gemspec", "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_experimental_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb"]
15
+ s.files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "ext/extconf-make.rb", "ext/extconf.rb", "ext/libmemcached-0.32.tar.gz", "ext/libmemcached-2.patch", "ext/libmemcached-3.patch", "ext/libmemcached-4.patch", "ext/libmemcached-5.patch", "ext/libmemcached-6.patch", "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/experimental.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_experimental_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "memcached.gemspec"]
16
16
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/memcached/}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Memcached", "--main", "README"]
18
18
  s.require_paths = ["lib", "ext"]
@@ -1,7 +1,7 @@
1
1
 
2
2
  HERE = File.dirname(__FILE__)
3
3
  $LOAD_PATH << "#{HERE}/../../lib/"
4
- UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
4
+ UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
5
5
 
6
6
  require 'memcached'
7
7
  require 'benchmark'
@@ -14,12 +14,13 @@ puts `ruby -v`
14
14
  puts `env | egrep '^RUBY'`
15
15
  puts "Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
16
16
 
17
- [ ["memcached", "memcached"],
18
- ["remix-stash", "remix/stash"],
17
+ [ ["memcached", "memcached"],
18
+ ["remix-stash", "remix/stash"],
19
19
  # ["astro-remcached", "remcached"], # Clobbers the "Memcached" constant
20
20
  ["memcache-client", "memcache"],
21
21
  ["kgio", "kgio"],
22
- ["dalli","dalli"]].each do |gem_name, requirement|
22
+ ["dalli","dalli"]
23
+ ].each do |gem_name, requirement|
23
24
  require requirement
24
25
  gem gem_name
25
26
  puts "Loaded #{gem_name} #{Gem.loaded_specs[gem_name].version.to_s rescue nil}"
@@ -47,7 +48,7 @@ class Dalli::ClientCompat < Dalli::Client
47
48
  def prepend(*args)
48
49
  super
49
50
  rescue Dalli::DalliError
50
- end
51
+ end
51
52
  end
52
53
 
53
54
  class Bench
@@ -55,12 +56,13 @@ class Bench
55
56
  def initialize(loops = nil, stack_depth = nil)
56
57
  @loops = (loops || 20000).to_i
57
58
  @stack_depth = (stack_depth || 0).to_i
58
-
59
+
60
+ puts "PID is #{Process.pid}"
59
61
  puts "Loops is #{@loops}"
60
62
  puts "Stack depth is #{@stack_depth}"
61
-
63
+
62
64
  @m_value = Marshal.dump(
63
- @small_value = ["testing"])
65
+ @small_value = ["testing"])
64
66
  @m_large_value = Marshal.dump(
65
67
  @large_value = [{"test" => "1", "test2" => "2", Object.new => "3", 4 => 4, "test5" => 2**65}] * 2048)
66
68
 
@@ -74,26 +76,26 @@ class Bench
74
76
  @k4 = "Medium" * 8,
75
77
  @k5 = "Medium2" * 8,
76
78
  @k6 = "Long3" * 40]
77
-
79
+
78
80
  reset_servers
79
81
  reset_clients
80
-
81
- Benchmark.bm(36) do |x|
82
- @benchmark = x
82
+
83
+ Benchmark.bm(36) do |x|
84
+ @benchmark = x
83
85
  end
84
86
  end
85
87
 
86
88
  def run(level = @stack_depth)
87
89
  level > 0 ? run(level - 1) : run_without_recursion
88
90
  end
89
-
91
+
90
92
  private
91
-
93
+
92
94
  def reset_servers
93
95
  system("ruby #{HERE}/../setup.rb")
94
96
  sleep(1)
95
97
  end
96
-
98
+
97
99
  def reset_clients
98
100
  @clients = {
99
101
  "libm:ascii" => Memcached::Rails.new(
@@ -113,34 +115,43 @@ class Bench
113
115
  :no_block => true, :buffer_requests => true, :namespace => "namespace", :binary_protocol => true),
114
116
  "mclient:ascii" => MemCache.new(['127.0.0.1:43042', '127.0.0.1:43043']),
115
117
  "stash:bin" => Remix::Stash.new(:root),
116
- "dalli:bin" => Dalli::ClientCompat.new(['127.0.0.1:43042', '127.0.0.1:43043'], :marshal => false, :threadsafe => false)}
118
+ "dalli:bin" => Dalli::ClientCompat.new(['127.0.0.1:43042', '127.0.0.1:43043'], :marshal => false, :threadsafe => false)
119
+ }
117
120
  end
118
-
119
-
120
- def benchmark_clients(test_name, clients = @clients)
121
- clients.keys.sort.each do |client_name|
121
+
122
+ def benchmark_clients(test_name, populate_keys = true)
123
+ @clients.keys.sort.each do |client_name|
122
124
  next if client_name == "stash" and test_name == "set-large" # Don't let stash break the world
123
- client = clients[client_name]
125
+ client = @clients[client_name]
124
126
  begin
127
+ if populate_keys
128
+ client.set @k1, @m_value, 0, true
129
+ client.set @k2, @m_value, 0, true
130
+ client.set @k3, @m_value, 0, true
131
+ else
132
+ client.delete @k1
133
+ client.delete @k2
134
+ client.delete @k3
135
+ end
125
136
  yield client
126
137
  @benchmark.report("#{test_name}: #{client_name}") { @loops.times { yield client } }
127
138
  rescue Exception => e
128
- puts "#{test_name}:#{client_name} => #{e.inspect}"
139
+ puts "#{test_name}: #{client_name} => #{e.inspect}" if ENV["DEBUG"]
129
140
  reset_clients
130
141
  end
131
142
  end
132
143
  puts
133
144
  end
134
-
145
+
135
146
  def benchmark_hashes(hashes, test_name)
136
147
  hashes.each do |hash_name, int|
137
148
  @m = Memcached::Rails.new(:hash => hash_name)
138
149
  @benchmark.report("#{test_name}:#{hash_name}") do
139
150
  (@loops * 5).times { yield int }
140
151
  end
141
- end
152
+ end
142
153
  end
143
-
154
+
144
155
  def run_without_recursion
145
156
  benchmark_clients("set") do |c|
146
157
  c.set @k1, @m_value, 0, true
@@ -153,47 +164,47 @@ class Bench
153
164
  c.get @k2, true
154
165
  c.get @k3, true
155
166
  end
156
-
167
+
157
168
  benchmark_clients("get-multi") do |c|
158
169
  c.get_multi @keys, true
159
170
  end
160
-
171
+
161
172
  benchmark_clients("append") do |c|
162
173
  c.append @k1, @m_value
163
174
  c.append @k2, @m_value
164
175
  c.append @k3, @m_value
165
- end
176
+ end
166
177
 
167
178
  benchmark_clients("prepend") do |c|
168
179
  c.prepend @k1, @m_value
169
180
  c.prepend @k2, @m_value
170
181
  c.prepend @k3, @m_value
171
- end
172
-
173
- benchmark_clients("delete") do |c|
182
+ end
183
+
184
+ benchmark_clients("delete") do |c|
174
185
  c.delete @k1
175
186
  c.delete @k2
176
187
  c.delete @k3
177
188
  end
178
-
179
- benchmark_clients("get-missing") do |c|
189
+
190
+ benchmark_clients("get-missing", false) do |c|
180
191
  c.get @k1
181
192
  c.get @k2
182
193
  c.get @k3
183
194
  end
184
195
 
185
- benchmark_clients("append-missing") do |c|
196
+ benchmark_clients("append-missing", false) do |c|
186
197
  c.append @k1, @m_value
187
198
  c.append @k2, @m_value
188
199
  c.append @k3, @m_value
189
200
  end
190
201
 
191
- benchmark_clients("prepend-missing") do |c|
202
+ benchmark_clients("prepend-missing", false) do |c|
192
203
  c.prepend @k1, @m_value
193
204
  c.prepend @k2, @m_value
194
205
  c.prepend @k3, @m_value
195
206
  end
196
-
207
+
197
208
  benchmark_clients("set-large") do |c|
198
209
  c.set @k1, @m_large_value, 0, true
199
210
  c.set @k2, @m_large_value, 0, true
@@ -205,14 +216,14 @@ class Bench
205
216
  c.get @k2, true
206
217
  c.get @k3, true
207
218
  end
208
-
219
+
209
220
  benchmark_hashes(Memcached::HASH_VALUES, "hash") do |i|
210
221
  Rlibmemcached.memcached_generate_hash_rvalue(@k1, i)
211
222
  Rlibmemcached.memcached_generate_hash_rvalue(@k2, i)
212
223
  Rlibmemcached.memcached_generate_hash_rvalue(@k3, i)
213
224
  Rlibmemcached.memcached_generate_hash_rvalue(@k4, i)
214
225
  Rlibmemcached.memcached_generate_hash_rvalue(@k5, i)
215
- Rlibmemcached.memcached_generate_hash_rvalue(@k6, i)
226
+ Rlibmemcached.memcached_generate_hash_rvalue(@k6, i)
216
227
  end
217
228
  end
218
229
  end
@@ -1,26 +1,26 @@
1
-
1
+
2
2
  unless defined? UNIX_SOCKET_NAME
3
3
  HERE = File.dirname(__FILE__)
4
4
  UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
5
-
5
+
6
6
  # Kill memcached
7
7
  system("killall -9 memcached")
8
-
8
+
9
9
  # Start memcached
10
10
  verbosity = (ENV['DEBUG'] ? "-vv" : "")
11
11
  log = "/tmp/memcached.log"
12
12
  system ">#{log}"
13
-
13
+
14
14
  # TCP memcached
15
15
  (43042..43046).each do |port|
16
16
  cmd = "memcached #{verbosity} -U 0 -p #{port} >> #{log} 2>&1 &"
17
17
  raise "'#{cmd}' failed to start" unless system(cmd)
18
- end
18
+ end
19
19
  # UDP memcached
20
20
  (43052..43053).each do |port|
21
21
  cmd = "memcached #{verbosity} -U #{port} -p 0 >> #{log} 2>&1 &"
22
22
  raise "'#{cmd}' failed to start" unless system(cmd)
23
- end
23
+ end
24
24
  # Domain socket memcached
25
25
  (0..1).each do |i|
26
26
  cmd = "memcached -M -s #{UNIX_SOCKET_NAME}#{i} #{verbosity} >> #{log} 2>&1 &"
@@ -3,11 +3,13 @@ $LOAD_PATH << "#{File.dirname(__FILE__)}/../lib"
3
3
 
4
4
  require 'rubygems'
5
5
  require 'mocha'
6
+ require 'socket'
7
+ require 'benchmark'
6
8
 
7
9
  if ENV['DEBUG']
8
- require 'ruby-debug'
10
+ require 'ruby-debug'
9
11
  end
10
-
12
+
11
13
  require 'memcached'
12
14
  require 'test/unit'
13
15
  require 'ostruct'
@@ -16,3 +18,4 @@ UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached') unless defined?
16
18
 
17
19
  class GenericClass
18
20
  end
21
+
@@ -1,8 +1,5 @@
1
1
 
2
2
  require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
3
- require 'socket'
4
- require 'mocha'
5
- require 'benchmark'
6
3
 
7
4
  class MemcachedExperimentalTest < Test::Unit::TestCase
8
5
 
@@ -1,8 +1,5 @@
1
1
 
2
2
  require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
3
- require 'socket'
4
- require 'mocha'
5
- require 'benchmark'
6
3
 
7
4
  class MemcachedTest < Test::Unit::TestCase
8
5
 
@@ -144,7 +141,7 @@ class MemcachedTest < Test::Unit::TestCase
144
141
 
145
142
  def test_set_prefix_key_to_empty_string
146
143
  cache = Memcached.new @servers, :prefix_key => "foo"
147
- cache.prefix_key = ""
144
+ cache.prefix_key = ""
148
145
  assert_equal "", cache.prefix_key
149
146
  end
150
147
 
@@ -388,7 +385,7 @@ class MemcachedTest < Test::Unit::TestCase
388
385
  @cache.get(["#{key}_1", "#{key}_2"])
389
386
  )
390
387
  end
391
-
388
+
392
389
  def test_get_multi_empty_string
393
390
  @cache.set "#{key}_1", "", 0, false
394
391
  assert_equal({"#{key}_1" => ""},
@@ -469,6 +466,10 @@ class MemcachedTest < Test::Unit::TestCase
469
466
  assert_raise(Memcached::NotFound) do
470
467
  @cache.get key
471
468
  end
469
+
470
+ assert_raise(TypeError) do
471
+ @cache.set key, @value, Time.now
472
+ end
472
473
  end
473
474
 
474
475
  def test_set_with_default_ttl
@@ -1121,7 +1122,7 @@ class MemcachedTest < Test::Unit::TestCase
1121
1122
  :distribution => :random,
1122
1123
  :server_failure_limit => 1,
1123
1124
  :retry_timeout => 1,
1124
- :exception_retry_limit => 0
1125
+ :exception_retry_limit => 0
1125
1126
  )
1126
1127
 
1127
1128
  # Provoke the errors in 'failures'