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 +13 -0
- data/README.md +1 -1
- data/lib/action_dispatch/middleware/session/dalli_store.rb +1 -1
- data/lib/active_support/cache/dalli_store.rb +8 -11
- data/lib/dalli/client.rb +13 -8
- data/lib/dalli/ring.rb +5 -5
- data/lib/dalli/socket.rb +18 -9
- data/lib/dalli/version.rb +1 -1
- data/lib/rack/session/dalli.rb +52 -0
- data/test/benchmark_test.rb +2 -2
- data/test/memcached_mock.rb +2 -2
- data/test/test_active_support.rb +9 -0
- data/test/test_dalli.rb +1 -1
- metadata +11 -10
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, :
|
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.
|
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
|
-
|
44
|
-
|
45
|
-
|
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
|
data/lib/dalli/client.rb
CHANGED
@@ -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 || '
|
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
|
data/lib/dalli/ring.rb
CHANGED
@@ -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!
|
data/lib/dalli/socket.rb
CHANGED
@@ -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
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
data/lib/dalli/version.rb
CHANGED
@@ -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
|
data/test/benchmark_test.rb
CHANGED
data/test/memcached_mock.rb
CHANGED
@@ -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}"
|
data/test/test_active_support.rb
CHANGED
@@ -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')
|
data/test/test_dalli.rb
CHANGED
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.
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *70233391291560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mocha
|
27
|
-
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: *
|
35
|
+
version_requirements: *70233391290560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rails
|
38
|
-
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: *
|
46
|
+
version_requirements: *70233391290000
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: memcache-client
|
49
|
-
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: *
|
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
|