dalli 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dalli might be problematic. Click here for more details.

data/History.md CHANGED
@@ -1,6 +1,19 @@
1
1
  Dalli Changelog
2
2
  =====================
3
3
 
4
+ 1.1.4
5
+ =======
6
+
7
+ - Use 127.0.0.1 instead of localhost as default to avoid IPv6 issues
8
+ - Extend DalliStore's :expires\_in when :race\_condition\_ttl is also used.
9
+ - Fix :expires\_in option not propogating from DalliStore to Client, GH-136
10
+ - Added support for native Rack session store. Until now, Dalli's
11
+ session store has required Rails. Now you can use Dalli to store
12
+ sessions for any Rack application.
13
+
14
+ require 'rack/session/dalli'
15
+ use Rack::Session::Dalli, :memcache_server => 'localhost:11211', :compression => true
16
+
4
17
  1.1.3
5
18
  =======
6
19
 
data/README.md CHANGED
@@ -80,7 +80,7 @@ In `config/environments/production.rb`:
80
80
  A more comprehensive example (note that we are setting a reasonable default for maximum cache entry lifetime (one day), enabling compression for large values, and namespacing all entries for this rails app. Remove the namespace if you have multiple apps which share cached values):
81
81
 
82
82
  config.cache_store = :dalli_store, 'cache-1.example.com', 'cache-2.example.com',
83
- { :namespace => NAME_OF_RAILS_APP, :expires_in => 1.day, :compress => true }
83
+ { :namespace => NAME_OF_RAILS_APP, :expires_in => 1.day, :compression => true }
84
84
 
85
85
  To use Dalli for Rails session storage, in `config/initializers/session_store.rb`:
86
86
 
@@ -15,7 +15,7 @@ module ActionDispatch
15
15
  @default_options = { :namespace => 'rack:session' }.merge(@default_options)
16
16
 
17
17
  @pool = options[:cache] || begin
18
- Dalli::Client.new(
18
+ Dalli::Client.new(
19
19
  @default_options[:memcache_server], @default_options)
20
20
  end
21
21
  @namespace = @default_options[:namespace]
@@ -6,11 +6,12 @@ rescue LoadError => e
6
6
  raise e
7
7
  end
8
8
  require 'digest/md5'
9
+ require 'active_support/cache'
9
10
 
10
11
  module ActiveSupport
11
12
  module Cache
12
13
  # A cache store implementation which stores data in Memcached:
13
- # http://www.danga.com/memcached/
14
+ # http://www.memcached.org
14
15
  #
15
16
  # DalliStore implements the Strategy::LocalCache strategy which implements
16
17
  # an in memory cache inside of a block.
@@ -19,13 +20,6 @@ module ActiveSupport
19
20
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/
20
21
  RAW = { :raw => true }
21
22
 
22
- def self.build_mem_cache(*addresses)
23
- addresses = addresses.flatten
24
- options = addresses.extract_options!
25
- addresses = ["localhost:11211"] if addresses.empty?
26
- Dalli::Client.new(addresses, options)
27
- end
28
-
29
23
  # Creates a new DalliStore object, with the given memcached server
30
24
  # addresses. Each address is either a host name, or a host-with-port string
31
25
  # in the form of "host_name:port". For example:
@@ -40,9 +34,12 @@ module ActiveSupport
40
34
  options = addresses.extract_options!
41
35
  super(options)
42
36
 
43
- mem_cache_options = options.dup
44
- UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
45
- @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
37
+ addresses << 'localhost:11211' if addresses.empty?
38
+ options = options.dup
39
+ # Extend expiry by stale TTL or else memcached will never return stale data.
40
+ # See ActiveSupport::Cache#fetch.
41
+ options[:expires_in] += options[:race_condition_ttl] if options[:expires_in] && options[:race_condition_ttl]
42
+ @data = Dalli::Client.new(addresses, options)
46
43
 
47
44
  extend Strategy::LocalCache
48
45
  extend LocalCacheWithRaw
@@ -6,7 +6,7 @@ module Dalli
6
6
  # Dalli::Client is the main class which developers will use to interact with
7
7
  # the memcached server. Usage:
8
8
  #
9
- # Dalli::Client.new(['localhost:11211:10', 'cache-2.example.com:11211:5', '192.168.0.1:22122:5'],
9
+ # Dalli::Client.new(['localhost:11211:10', 'cache-2.example.com:11211:5', '192.168.0.1:22122:5'],
10
10
  # :threadsafe => true, :failover => true, :expires_in => 300)
11
11
  #
12
12
  # servers is an Array of "host:port:weight" where weight allows you to distribute cache unevenly.
@@ -30,7 +30,7 @@ module Dalli
30
30
  # - :async - assume its running inside the EM reactor. Requires em-synchrony to be installed. Default: false.
31
31
  #
32
32
  def initialize(servers=nil, options={})
33
- @servers = env_servers || servers || 'localhost:11211'
33
+ @servers = env_servers || servers || '127.0.0.1:11211'
34
34
  @options = { :expires_in => 0 }.merge(options)
35
35
  self.extend(Dalli::Client::MemcacheClientCompatibility) if Dalli::Client.compatibility_mode
36
36
  @ring = nil
@@ -184,13 +184,14 @@ module Dalli
184
184
  ##
185
185
  # Incr adds the given amount to the counter on the memcached server.
186
186
  # Amt must be a positive value.
187
- #
188
- # memcached counters are unsigned and cannot hold negative values. Calling
189
- # decr on a counter which is 0 will just return 0.
190
187
  #
191
188
  # If default is nil, the counter must already exist or the operation
192
189
  # will fail and will return nil. Otherwise this method will return
193
190
  # the new value for the counter.
191
+ #
192
+ # Note that the ttl will only apply if the counter does not already
193
+ # exist. To increase an existing counter and update its TTL, use
194
+ # #cas.
194
195
  def incr(key, amt=1, ttl=nil, default=nil)
195
196
  raise ArgumentError, "Positive values only: #{amt}" if amt < 0
196
197
  ttl ||= @options[:expires_in]
@@ -200,13 +201,17 @@ module Dalli
200
201
  ##
201
202
  # Decr subtracts the given amount from the counter on the memcached server.
202
203
  # Amt must be a positive value.
203
- #
204
+ #
204
205
  # memcached counters are unsigned and cannot hold negative values. Calling
205
206
  # decr on a counter which is 0 will just return 0.
206
207
  #
207
208
  # If default is nil, the counter must already exist or the operation
208
209
  # will fail and will return nil. Otherwise this method will return
209
210
  # the new value for the counter.
211
+ #
212
+ # Note that the ttl will only apply if the counter does not already
213
+ # exist. To decrease an existing counter and update its TTL, use
214
+ # #cas.
210
215
  def decr(key, amt=1, ttl=nil, default=nil)
211
216
  raise ArgumentError, "Positive values only: #{amt}" if amt < 0
212
217
  ttl ||= @options[:expires_in]
@@ -263,7 +268,7 @@ module Dalli
263
268
  retry
264
269
  end
265
270
  end
266
-
271
+
267
272
  def validate_key(key)
268
273
  raise ArgumentError, "illegal character in key #{key}" if key.respond_to?(:ascii_only?) && !key.ascii_only?
269
274
  raise ArgumentError, "illegal character in key #{key}" if key =~ /\s/
@@ -271,7 +276,7 @@ module Dalli
271
276
  raise ArgumentError, "key cannot be blank" if key.nil? || key.strip.size == 0
272
277
  raise ArgumentError, "key too long #{key.inspect}" if key.length > 250
273
278
  end
274
-
279
+
275
280
  def key_with_namespace(key)
276
281
  @options[:namespace] ? "#{@options[:namespace]}:#{key}" : key
277
282
  end
@@ -4,9 +4,9 @@ require 'zlib'
4
4
  module Dalli
5
5
  class Ring
6
6
  POINTS_PER_SERVER = 160 # this is the default in libmemcached
7
-
7
+
8
8
  attr_accessor :servers, :continuum
9
-
9
+
10
10
  def initialize(servers, options)
11
11
  @servers = servers
12
12
  @continuum = nil
@@ -26,7 +26,7 @@ module Dalli
26
26
  threadsafe! unless options[:threadsafe] == false
27
27
  @failover = options[:failover] != false
28
28
  end
29
-
29
+
30
30
  def server_for_key(key)
31
31
  if @continuum
32
32
  hkey = hash_for(key)
@@ -44,7 +44,7 @@ module Dalli
44
44
 
45
45
  raise Dalli::RingError, "No server available"
46
46
  end
47
-
47
+
48
48
  def lock
49
49
  @servers.each { |s| s.lock! }
50
50
  begin
@@ -53,7 +53,7 @@ module Dalli
53
53
  @servers.each { |s| s.unlock! }
54
54
  end
55
55
  end
56
-
56
+
57
57
  private
58
58
 
59
59
  def threadsafe!
@@ -28,7 +28,7 @@ begin
28
28
  loop do
29
29
  value << kgio_read!(count - value.bytesize)
30
30
  break if value.bytesize == count
31
- end
31
+ end
32
32
  value
33
33
  end
34
34
 
@@ -149,13 +149,22 @@ rescue LoadError
149
149
  puts "Could not define alternate em-synchrony socket IO" if defined?($TESTING) && $TESTING
150
150
  end
151
151
 
152
- class Dalli::Server::USocket < UNIXSocket
153
- def readfull(count)
154
- value = ''
155
- loop do
156
- value << read(count - value.bytesize)
157
- break if value.bytesize == count
158
- end
159
- value
152
+ require 'rbconfig'
153
+ if RbConfig::CONFIG['host_os'] =~ /mingw|mswin/
154
+ class Dalli::Server::USocket
155
+ def initialize(*args)
156
+ raise Dalli::DalliError, "Unix sockets are not supported on Windows platform."
157
+ end
158
+ end
159
+ else
160
+ class Dalli::Server::USocket < UNIXSocket
161
+ def readfull(count)
162
+ value = ''
163
+ loop do
164
+ value << read(count - value.bytesize)
165
+ break if value.bytesize == count
166
+ end
167
+ value
168
+ end
160
169
  end
161
170
  end
@@ -1,3 +1,3 @@
1
1
  module Dalli
2
- VERSION = '1.1.3'
2
+ VERSION = '1.1.4'
3
3
  end
@@ -0,0 +1,52 @@
1
+ require 'rack/session/abstract/id'
2
+ require 'dalli'
3
+
4
+ module Rack
5
+ module Session
6
+ class Dalli < Abstract::ID
7
+ attr_reader :pool
8
+
9
+ DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
10
+ :namespace => 'rack:session',
11
+ :memcache_server => 'localhost:11211'
12
+
13
+ def initialize(app, options={})
14
+ super
15
+ mserv = @default_options[:memcache_server]
16
+ mopts = @default_options.reject{|k,v| !DEFAULT_OPTIONS.include? k }
17
+ @pool = options[:cache] || Dalli::Client.new(mserv, mopts)
18
+ end
19
+
20
+ def generate_sid
21
+ loop do
22
+ sid = super
23
+ break sid unless @pool.get(sid)
24
+ end
25
+ end
26
+
27
+ def get_session(env, sid)
28
+ unless sid and session = @pool.get(sid)
29
+ sid, session = generate_sid, {}
30
+ unless @pool.add(sid, session)
31
+ raise "Session collision on '#{sid.inspect}'"
32
+ end
33
+ end
34
+ [sid, session]
35
+ end
36
+
37
+ def set_session(env, session_id, new_session, options)
38
+ expiry = options[:expire_after]
39
+ expiry = expiry.nil? ? 0 : expiry + 1
40
+
41
+ @pool.set session_id, new_session, expiry
42
+ session_id
43
+ end
44
+
45
+ def destroy_session(env, session_id, options)
46
+ @pool.delete(session_id)
47
+ generate_sid unless options[:drop]
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -20,10 +20,10 @@ class TestBenchmark < Test::Unit::TestCase
20
20
  @key6 = "Long3"*40
21
21
  @counter = 'counter'
22
22
  end
23
-
23
+
24
24
  def test_benchmark
25
25
  memcached do
26
-
26
+
27
27
  Benchmark.bm(31) do |x|
28
28
 
29
29
  n = 2500
@@ -18,7 +18,7 @@ module MemcachedMock
18
18
  def self.tmp_socket_path
19
19
  "#{Dir.pwd}/tmp.sock"
20
20
  end
21
-
21
+
22
22
  module Helper
23
23
  # Forks the current process and starts a new mock Memcached server on
24
24
  # port 22122.
@@ -74,7 +74,7 @@ module MemcachedMock
74
74
  return unless supports_fork?
75
75
  Memcached.path ||= find_memcached
76
76
 
77
- cmd = if options[:unix]
77
+ cmd = if options[:unix]
78
78
  "#{Memcached.path}memcached #{args} -s #{MemcachedMock.tmp_socket_path}"
79
79
  else
80
80
  "#{Memcached.path}memcached #{args} -p #{port}"
@@ -180,6 +180,15 @@ class TestActiveSupport < Test::Unit::TestCase
180
180
  end
181
181
  end
182
182
 
183
+ should 'normalize options as expected' do
184
+ with_activesupport do
185
+ memcached do
186
+ @dalli = ActiveSupport::Cache::DalliStore.new('localhost:19122', :expires_in => 1, :race_condition_ttl => 1)
187
+ assert_equal 2, @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:expires_in]
188
+ end
189
+ end
190
+ end
191
+
183
192
  def connect
184
193
  @dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => 'x')
185
194
  @mc = ActiveSupport::Cache.lookup_store(:mem_cache_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => 'a')
@@ -22,7 +22,7 @@ class TestDalli < Test::Unit::TestCase
22
22
  assert_equal 1, ring.servers.size
23
23
  dc.close
24
24
 
25
- assert_equal s1, s2
25
+ assert_equal '127.0.0.1', s1
26
26
  assert_equal s2, s3
27
27
  end
28
28
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-26 00:00:00.000000000Z
12
+ date: 2011-12-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
16
- requirement: &2152632040 !ruby/object:Gem::Requirement
16
+ requirement: &70233391291560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2152632040
24
+ version_requirements: *70233391291560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mocha
27
- requirement: &2152630860 !ruby/object:Gem::Requirement
27
+ requirement: &70233391290560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2152630860
35
+ version_requirements: *70233391290560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rails
38
- requirement: &2152629740 !ruby/object:Gem::Requirement
38
+ requirement: &70233391290000 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 3.0.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2152629740
46
+ version_requirements: *70233391290000
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: memcache-client
49
- requirement: &2152628780 !ruby/object:Gem::Requirement
49
+ requirement: &70233391289240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 1.8.5
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2152628780
57
+ version_requirements: *70233391289240
58
58
  description: High performance memcached client for Ruby
59
59
  email: mperham@gmail.com
60
60
  executables: []
@@ -73,6 +73,7 @@ files:
73
73
  - lib/dalli/socket.rb
74
74
  - lib/dalli/version.rb
75
75
  - lib/dalli.rb
76
+ - lib/rack/session/dalli.rb
76
77
  - LICENSE
77
78
  - README.md
78
79
  - History.md