mperham-memcache-client 1.6.3 → 1.6.4

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/History.txt CHANGED
@@ -1,7 +1,18 @@
1
- = 1.6.3 (2009-02-10)
1
+ = 1.6.4 (2009-02-19)
2
+
3
+ * Remove native code altogether. The speedup was only 10% on Ruby 1.8.6 and did not work
4
+ on Ruby 1.9.1.
5
+
6
+ * Removed memcache_util.rb from the distribution. If you are using it, please copy the code
7
+ into your own project. The file will live in the github repository for a few more months
8
+ for this purposes. http://github.com/mperham/memcache-client/raw/7a276089aa3c914e47e3960f9740ac7377204970/lib/memcache_util.rb
9
+
10
+ * Roll continuum.rb into memcache.rb. The project is again a single Ruby file, with no dependencies.
11
+
12
+ = 1.6.3 (2009-02-14)
2
13
 
3
14
  * Remove gem native extension in preference to RubyInline. This allows the gem to install
4
- and work on JRuby.
15
+ and work on JRuby and Ruby 1.8.5 when the native code fails to compile.
5
16
 
6
17
  = 1.6.2 (2009-02-04)
7
18
 
data/lib/memcache.rb CHANGED
@@ -6,8 +6,6 @@ require 'timeout'
6
6
  require 'zlib'
7
7
  require 'digest/sha1'
8
8
 
9
- require 'continuum'
10
-
11
9
  ##
12
10
  # A Ruby client library for memcached.
13
11
  #
@@ -17,7 +15,7 @@ class MemCache
17
15
  ##
18
16
  # The version of MemCache you are using.
19
17
 
20
- VERSION = '1.6.2'
18
+ VERSION = '1.6.4'
21
19
 
22
20
  ##
23
21
  # Default options for the cache object.
@@ -120,6 +118,8 @@ class MemCache
120
118
 
121
119
  logger.info { "memcache-client #{VERSION} #{Array(servers).inspect}" } if logger
122
120
 
121
+ Thread.current[:memcache_client] = self.object_id if !@multithread
122
+
123
123
  self.servers = servers
124
124
  end
125
125
 
@@ -606,6 +606,8 @@ class MemCache
606
606
  # failures (but does still apply to unexpectedly lost connections etc.).
607
607
 
608
608
  def with_socket_management(server, &block)
609
+ check_multithread_status!
610
+
609
611
  @mutex.lock if @multithread
610
612
  retried = false
611
613
 
@@ -697,6 +699,18 @@ class MemCache
697
699
  ((total_servers * Continuum::POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
698
700
  end
699
701
 
702
+ def check_multithread_status!
703
+ return if @multithread
704
+
705
+ if Thread.current[:memcache_client] != self.object_id
706
+ raise MemCacheError, <<-EOM
707
+ You are accessing this memcache-client instance from multiple threads but have not enabled multithread support.
708
+ Normally: MemCache.new(['localhost:11211'], :multithread => true)
709
+ In Rails: config.cache_store = [:mem_cache_store, 'localhost:11211', { :multithread => true }]
710
+ EOM
711
+ end
712
+ end
713
+
700
714
  ##
701
715
  # This class represents a memcached server instance.
702
716
 
@@ -894,3 +908,42 @@ class TCPTimeoutSocket
894
908
  @sock.close
895
909
  end
896
910
  end
911
+
912
+ module Continuum
913
+ POINTS_PER_SERVER = 160 # this is the default in libmemcached
914
+
915
+ # Find the closest index in Continuum with value <= the given value
916
+ def self.binary_search(ary, value, &block)
917
+ upper = ary.size - 1
918
+ lower = 0
919
+ idx = 0
920
+
921
+ while(lower <= upper) do
922
+ idx = (lower + upper) / 2
923
+ comp = ary[idx].value <=> value
924
+
925
+ if comp == 0
926
+ return idx
927
+ elsif comp > 0
928
+ upper = idx - 1
929
+ else
930
+ lower = idx + 1
931
+ end
932
+ end
933
+ return upper
934
+ end
935
+
936
+ class Entry
937
+ attr_reader :value
938
+ attr_reader :server
939
+
940
+ def initialize(val, srv)
941
+ @value = val
942
+ @server = srv
943
+ end
944
+
945
+ def inspect
946
+ "<#{value}, #{server.host}:#{server.port}>"
947
+ end
948
+ end
949
+ end
@@ -333,6 +333,32 @@ class TestMemCache < Test::Unit::TestCase
333
333
  assert !server.alive?
334
334
  end
335
335
 
336
+ def test_multithread_error
337
+ server = FakeServer.new
338
+
339
+ # Write two messages to the socket to test failover
340
+ server.socket.data.write "bogus response\r\nbogus response\r\n"
341
+ server.socket.data.rewind
342
+
343
+ @cache.servers = []
344
+ @cache.servers << server
345
+
346
+ assert_nothing_raised do
347
+ @cache.set 'a', 1
348
+ end
349
+
350
+ passed = true
351
+ Thread.new do
352
+ begin
353
+ @cache.set 'b', 2
354
+ passed = false
355
+ rescue MemCache::MemCacheError => me
356
+ passed = me.message =~ /multiple threads/
357
+ end
358
+ end
359
+ assert passed
360
+ end
361
+
336
362
  def test_initialize
337
363
  cache = MemCache.new :namespace => 'my_namespace', :readonly => true
338
364
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mperham-memcache-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Hodel
@@ -11,19 +11,10 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-02-05 00:00:00 -08:00
14
+ date: 2009-02-13 00:00:00 -08:00
15
15
  default_executable:
16
- dependencies:
17
- - !ruby/object:Gem::Dependency
18
- name:
19
- - RubyInline
20
- version_requirement:
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: "0"
26
- version:
16
+ dependencies: []
17
+
27
18
  description: A Ruby library for accessing memcached.
28
19
  email: mperham@gmail.com
29
20
  executables: []
@@ -37,9 +28,7 @@ files:
37
28
  - LICENSE.txt
38
29
  - History.txt
39
30
  - Rakefile
40
- - lib/continuum.rb
41
31
  - lib/memcache.rb
42
- - lib/memcache_util.rb
43
32
  has_rdoc: false
44
33
  homepage: http://github.com/mperham/memcache-client
45
34
  post_install_message:
data/lib/continuum.rb DELETED
@@ -1,77 +0,0 @@
1
- module Continuum
2
- POINTS_PER_SERVER = 160 # this is the default in libmemcached
3
-
4
- class << self
5
-
6
- begin
7
- require 'inline'
8
- inline do |builder|
9
- builder.c <<-EOM
10
- int binary_search(VALUE ary, unsigned int r) {
11
- int upper = RARRAY_LEN(ary) - 1;
12
- int lower = 0;
13
- int idx = 0;
14
- ID value = rb_intern("value");
15
-
16
- while (lower <= upper) {
17
- idx = (lower + upper) / 2;
18
-
19
- VALUE continuumValue = rb_funcall(RARRAY_PTR(ary)[idx], value, 0);
20
- unsigned int l = NUM2UINT(continuumValue);
21
- if (l == r) {
22
- return idx;
23
- }
24
- else if (l > r) {
25
- upper = idx - 1;
26
- }
27
- else {
28
- lower = idx + 1;
29
- }
30
- }
31
- return upper;
32
- }
33
- EOM
34
- end
35
- rescue Exception => e
36
- puts "Unable to generate native code, falling back to Ruby: #{e.message}"
37
-
38
- # slow but pure ruby version
39
- # Find the closest index in Continuum with value <= the given value
40
- def binary_search(ary, value, &block)
41
- upper = ary.size - 1
42
- lower = 0
43
- idx = 0
44
-
45
- while(lower <= upper) do
46
- idx = (lower + upper) / 2
47
- comp = ary[idx].value <=> value
48
-
49
- if comp == 0
50
- return idx
51
- elsif comp > 0
52
- upper = idx - 1
53
- else
54
- lower = idx + 1
55
- end
56
- end
57
- return upper
58
- end
59
-
60
- end
61
- end
62
-
63
-
64
- class Entry
65
- attr_reader :value
66
- attr_reader :server
67
-
68
- def initialize(val, srv)
69
- @value = val
70
- @server = srv
71
- end
72
-
73
- def inspect
74
- "<#{value}, #{server.host}:#{server.port}>"
75
- end
76
- end
77
- end
data/lib/memcache_util.rb DELETED
@@ -1,102 +0,0 @@
1
- ##
2
- # A utility wrapper around the MemCache client to simplify cache access. All
3
- # methods silently ignore MemCache errors.
4
-
5
- module Cache
6
-
7
- ##
8
- # Try to return a logger object that does not rely
9
- # on ActiveRecord for logging.
10
- def self.logger
11
- @logger ||= if defined? Rails.logger # Rails 2.1 +
12
- Rails.logger
13
- elsif defined? RAILS_DEFAULT_LOGGER # Rails 1.2.2 +
14
- RAILS_DEFAULT_LOGGER
15
- else
16
- ActiveRecord::Base.logger # ... very old Rails.
17
- end
18
- end
19
- ##
20
- # Returns the object at +key+ from the cache if successful, or nil if either
21
- # the object is not in the cache or if there was an error attermpting to
22
- # access the cache.
23
- #
24
- # If there is a cache miss and a block is given the result of the block will
25
- # be stored in the cache with optional +expiry+, using the +add+ method rather
26
- # than +set+.
27
-
28
- def self.get(key, expiry = 0)
29
- start_time = Time.now
30
- value = CACHE.get key
31
- elapsed = Time.now - start_time
32
- logger.debug('MemCache Get (%0.6f) %s' % [elapsed, key])
33
- if value.nil? and block_given? then
34
- value = yield
35
- add key, value, expiry
36
- end
37
- value
38
- rescue MemCache::MemCacheError => err
39
- logger.debug "MemCache Error: #{err.message}"
40
- if block_given? then
41
- value = yield
42
- put key, value, expiry
43
- end
44
- value
45
- end
46
-
47
- ##
48
- # Sets +value+ in the cache at +key+, with an optional +expiry+ time in
49
- # seconds.
50
-
51
- def self.put(key, value, expiry = 0)
52
- start_time = Time.now
53
- CACHE.set key, value, expiry
54
- elapsed = Time.now - start_time
55
- logger.debug('MemCache Set (%0.6f) %s' % [elapsed, key])
56
- value
57
- rescue MemCache::MemCacheError => err
58
- ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
59
- nil
60
- end
61
-
62
- ##
63
- # Sets +value+ in the cache at +key+, with an optional +expiry+ time in
64
- # seconds. If +key+ already exists in cache, returns nil.
65
-
66
- def self.add(key, value, expiry = 0)
67
- start_time = Time.now
68
- response = CACHE.add key, value, expiry
69
- elapsed = Time.now - start_time
70
- logger.debug('MemCache Add (%0.6f) %s' % [elapsed, key])
71
- (response == "STORED\r\n") ? value : nil
72
- rescue MemCache::MemCacheError => err
73
- ActiveRecord::Base.logger.debug "MemCache Error: #{err.message}"
74
- nil
75
- end
76
-
77
- ##
78
- # Deletes +key+ from the cache in +delay+ seconds.
79
-
80
- def self.delete(key, delay = nil)
81
- start_time = Time.now
82
- CACHE.delete key, delay
83
- elapsed = Time.now - start_time
84
- logger.debug('MemCache Delete (%0.6f) %s' %
85
- [elapsed, key])
86
- nil
87
- rescue MemCache::MemCacheError => err
88
- logger.debug "MemCache Error: #{err.message}"
89
- nil
90
- end
91
-
92
- ##
93
- # Resets all connections to MemCache servers.
94
-
95
- def self.reset
96
- CACHE.reset
97
- logger.debug 'MemCache Connections Reset'
98
- nil
99
- end
100
-
101
- end
102
-