dalli 1.0.1 → 1.0.2
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 +9 -0
- data/Performance.md +23 -57
- data/README.md +1 -0
- data/Upgrade.md +12 -0
- data/lib/action_controller/session/dalli_store.rb +1 -1
- data/lib/action_dispatch/middleware/session/dalli_store.rb +1 -1
- data/lib/dalli/client.rb +14 -0
- data/lib/dalli/compatibility.rb +52 -0
- data/lib/dalli/memcache-client.rb +1 -0
- data/lib/dalli/server.rb +5 -5
- data/lib/dalli/version.rb +1 -1
- data/test/test_compatibility.rb +33 -0
- data/test/test_session_store.rb +28 -3
- metadata +7 -3
data/History.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
Dalli Changelog
|
2
2
|
=====================
|
3
3
|
|
4
|
+
1.0.2
|
5
|
+
=======
|
6
|
+
|
7
|
+
- Allow browser session cookies (blindsey)
|
8
|
+
- Compatibility fixes (mwynholds)
|
9
|
+
- Add backwards compatibility module for memcache-client, require 'dalli/memcache-client'. It makes
|
10
|
+
Dalli more compatible with memcache-client and prints out a warning any time you do something that
|
11
|
+
is no longer supported so you can fix your code.
|
12
|
+
|
4
13
|
1.0.1
|
5
14
|
=======
|
6
15
|
|
data/Performance.md
CHANGED
@@ -2,68 +2,34 @@ Performance
|
|
2
2
|
====================
|
3
3
|
|
4
4
|
Caching is all about performance, so I carefully track Dalli performance to ensure no regressions.
|
5
|
-
Times are from a Unibody MBP 2.4Ghz Core
|
5
|
+
Times are from a Unibody MBP 2.4Ghz Core i5 running Snow Leopard.
|
6
6
|
|
7
7
|
You can optionally use kgio to give Dalli a small, 10-20% performance boost: gem install kgio.
|
8
8
|
|
9
9
|
*memcache-client*:
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
Testing 1.8.5 with ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
|
12
|
+
user system total real
|
13
|
+
set:plain:memcache-client 1.950000 0.320000 2.270000 ( 2.271513)
|
14
|
+
set:ruby:memcache-client 2.040000 0.310000 2.350000 ( 2.355625)
|
15
|
+
get:plain:memcache-client 2.160000 0.330000 2.490000 ( 2.499911)
|
16
|
+
get:ruby:memcache-client 2.310000 0.340000 2.650000 ( 2.659208)
|
17
|
+
multiget:ruby:memcache-client 1.050000 0.130000 1.180000 ( 1.168383)
|
18
|
+
missing:ruby:memcache-client 2.050000 0.320000 2.370000 ( 2.384290)
|
19
|
+
mixed:ruby:memcache-client 4.440000 0.660000 5.100000 ( 5.148145)
|
20
20
|
|
21
21
|
*dalli*:
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
set:ruby:dalli 1.460000 0.320000 1.780000 ( 1.851925)
|
37
|
-
get:plain:dalli 1.420000 0.350000 1.770000 ( 1.866443)
|
38
|
-
get:ruby:dalli 1.570000 0.380000 1.950000 ( 2.028747)
|
39
|
-
multiget:ruby:dalli 0.870000 0.300000 1.170000 ( 1.295592)
|
40
|
-
missing:ruby:dalli 1.420000 0.370000 1.790000 ( 1.925094)
|
41
|
-
mixed:ruby:dalli 2.800000 0.680000 3.480000 ( 3.820694)
|
42
|
-
|
43
|
-
Testing 0.11.1 with ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
44
|
-
Using standard socket IO
|
45
|
-
user system total real
|
46
|
-
set:plain:dalli 1.570000 0.380000 1.950000 ( 1.990252)
|
47
|
-
setq:plain:dalli 0.460000 0.140000 0.600000 ( 0.600362)
|
48
|
-
set:ruby:dalli 1.630000 0.380000 2.010000 ( 2.050056)
|
49
|
-
get:plain:dalli 1.710000 0.410000 2.120000 ( 2.156428)
|
50
|
-
get:ruby:dalli 1.680000 0.410000 2.090000 ( 2.120228)
|
51
|
-
multiget:ruby:dalli 0.860000 0.310000 1.170000 ( 1.182857)
|
52
|
-
missing:ruby:dalli 1.540000 0.390000 1.930000 ( 1.976637)
|
53
|
-
mixed:ruby:dalli 3.300000 0.810000 4.110000 ( 4.166230)
|
54
|
-
mixedq:ruby:dalli 2.530000 0.640000 3.170000 ( 3.214916)
|
55
|
-
incr:ruby:dalli 0.540000 0.140000 0.680000 ( 0.691829)
|
56
|
-
|
57
|
-
Testing 0.11.1 with ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
58
|
-
Using kgio socket IO
|
59
|
-
user system total real
|
60
|
-
set:plain:dalli 0.800000 0.370000 1.170000 ( 1.694842)
|
61
|
-
setq:plain:dalli 0.460000 0.150000 0.610000 ( 0.618146)
|
62
|
-
set:ruby:dalli 0.860000 0.370000 1.230000 ( 1.760995)
|
63
|
-
get:plain:dalli 0.910000 0.390000 1.300000 ( 1.860499)
|
64
|
-
get:ruby:dalli 0.900000 0.390000 1.290000 ( 1.809426)
|
65
|
-
multiget:ruby:dalli 0.720000 0.300000 1.020000 ( 1.044887)
|
66
|
-
missing:ruby:dalli 0.770000 0.400000 1.170000 ( 1.649516)
|
67
|
-
mixed:ruby:dalli 1.750000 0.760000 2.510000 ( 3.563845)
|
68
|
-
mixedq:ruby:dalli 1.730000 0.650000 2.380000 ( 2.883827)
|
69
|
-
incr:ruby:dalli 0.280000 0.130000 0.410000 ( 0.603845)
|
23
|
+
Using kgio socket IO
|
24
|
+
Testing 1.0.1 with ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
|
25
|
+
user system total real
|
26
|
+
set:plain:dalli 0.840000 0.300000 1.140000 ( 1.516160)
|
27
|
+
setq:plain:dalli 0.510000 0.120000 0.630000 ( 0.634174)
|
28
|
+
set:ruby:dalli 0.880000 0.300000 1.180000 ( 1.549591)
|
29
|
+
get:plain:dalli 0.970000 0.330000 1.300000 ( 1.621385)
|
30
|
+
get:ruby:dalli 0.970000 0.340000 1.310000 ( 1.622811)
|
31
|
+
multiget:ruby:dalli 0.800000 0.250000 1.050000 ( 1.453479)
|
32
|
+
missing:ruby:dalli 0.820000 0.330000 1.150000 ( 1.453847)
|
33
|
+
mixed:ruby:dalli 1.850000 0.640000 2.490000 ( 3.189240)
|
34
|
+
mixedq:ruby:dalli 1.820000 0.530000 2.350000 ( 2.611830)
|
35
|
+
incr:ruby:dalli 0.310000 0.110000 0.420000 ( 0.545641)
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ So a few notes. Dalli:
|
|
29
29
|
4. is approx 700 lines of Ruby. memcache-client is approx 1250 lines.
|
30
30
|
5. supports SASL for use in managed environments, e.g. Heroku.
|
31
31
|
6. provides proper failover with recovery and adjustable timeouts
|
32
|
+
7. has a backwards-compatibility mode for people migrating from memcache-client (see Upgrade.md).
|
32
33
|
|
33
34
|
|
34
35
|
Installation and Usage
|
data/Upgrade.md
CHANGED
@@ -4,6 +4,17 @@ Upgrading from memcache-client
|
|
4
4
|
Dalli is not meant to be 100% compatible with memcache-client, there are a few minor differences in the API.
|
5
5
|
|
6
6
|
|
7
|
+
Compatibility Layer
|
8
|
+
----------------------
|
9
|
+
|
10
|
+
Enable memcache-client compatibility in your application when upgrading by requiring this when
|
11
|
+
initalizing your app:
|
12
|
+
|
13
|
+
require 'dalli/memcache-client'
|
14
|
+
|
15
|
+
This will print out warnings if your code is using the old memcache-client API style, explained below.
|
16
|
+
|
17
|
+
|
7
18
|
Marshalling
|
8
19
|
---------------
|
9
20
|
|
@@ -31,3 +42,4 @@ In memcache-client, `set(key, value)` normally returns "STORED\r\n". This is an
|
|
31
42
|
set
|
32
43
|
add
|
33
44
|
replace
|
45
|
+
delete
|
@@ -45,7 +45,7 @@ module ActionDispatch
|
|
45
45
|
|
46
46
|
def set_session(env, sid, session_data, options = nil)
|
47
47
|
options ||= env[ENV_SESSION_OPTIONS_KEY]
|
48
|
-
expiry = options[:expire_after]
|
48
|
+
expiry = options[:expire_after]
|
49
49
|
@pool.set(sid, session_data, expiry)
|
50
50
|
sid
|
51
51
|
rescue Dalli::DalliError
|
data/lib/dalli/client.rb
CHANGED
@@ -24,6 +24,19 @@ module Dalli
|
|
24
24
|
def initialize(servers=nil, options={})
|
25
25
|
@servers = env_servers || servers || 'localhost:11211'
|
26
26
|
@options = { :expires_in => 0 }.merge(options)
|
27
|
+
self.extend(Dalli::Client::MemcacheClientCompatibility) if Dalli::Client.compatibility_mode
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Turn on compatibility mode, which mixes in methods in memcache_client_compatibility.rb
|
32
|
+
# This value is set to true in memcache-client.rb.
|
33
|
+
def self.compatibility_mode
|
34
|
+
@compatibility_mode ||= false
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.compatibility_mode=(compatibility_mode)
|
38
|
+
require 'dalli/compatibility'
|
39
|
+
@compatibility_mode = compatibility_mode
|
27
40
|
end
|
28
41
|
|
29
42
|
#
|
@@ -107,6 +120,7 @@ module Dalli
|
|
107
120
|
end
|
108
121
|
|
109
122
|
def set(key, value, ttl=nil, options=nil)
|
123
|
+
raise "Invalid API usage, please require 'dalli/memcache-client' for compatibility, see Upgrade.md" if options == true
|
110
124
|
ttl ||= @options[:expires_in]
|
111
125
|
perform(:set, key, value, ttl, options)
|
112
126
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class Dalli::Client
|
2
|
+
|
3
|
+
module MemcacheClientCompatibility
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
Dalli.logger.error("Starting Dalli in memcache-client compatibility mode")
|
7
|
+
super(*args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(key, value, ttl = nil, options = nil)
|
11
|
+
if options == true || options == false
|
12
|
+
Dalli.logger.error("Dalli: please use set(key, value, ttl, :raw => boolean): #{caller[0]}")
|
13
|
+
options = { :raw => options }
|
14
|
+
end
|
15
|
+
super(key, value, ttl, options) ? "STORED\r\n" : "NOT_STORED\r\n"
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(key, value, ttl = nil, options = nil)
|
20
|
+
if options == true || options == false
|
21
|
+
Dalli.logger.error("Dalli: please use add(key, value, ttl, :raw => boolean): #{caller[0]}")
|
22
|
+
options = { :raw => options }
|
23
|
+
end
|
24
|
+
super(key, value, ttl, options) ? "STORED\r\n" : "NOT_STORED\r\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
def replace(key, value, ttl = nil, options = nil)
|
28
|
+
if options == true || options == false
|
29
|
+
Dalli.logger.error("Dalli: please use replace(key, value, ttl, :raw => boolean): #{caller[0]}")
|
30
|
+
options = { :raw => options }
|
31
|
+
end
|
32
|
+
super(key, value, ttl, options) ? "STORED\r\n" : "NOT_STORED\r\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Dalli does not unmarshall data that does not have the marshalled flag set so we need
|
36
|
+
# to unmarshall manually any marshalled data originally put in memcached by memcache-client.
|
37
|
+
# Peek at the data and see if it looks marshalled.
|
38
|
+
def get(key, options = nil)
|
39
|
+
value = super(key, options)
|
40
|
+
if value && value.is_a?(String) && !options && value.size > 2 &&
|
41
|
+
bytes = value.unpack('cc') && bytes[0] == 4 && bytes[1] == 8
|
42
|
+
return Marshal.load(value) rescue value
|
43
|
+
end
|
44
|
+
value
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete(key)
|
48
|
+
super(key) ? "DELETED\r\n" : "NOT_DELETED\r\n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dalli::Client.compatibility_mode = true
|
data/lib/dalli/server.rb
CHANGED
@@ -147,7 +147,7 @@ module Dalli
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def set(key, value, ttl, options)
|
150
|
-
(value, flags) = serialize(value, options)
|
150
|
+
(value, flags) = serialize(key, value, options)
|
151
151
|
|
152
152
|
req = [REQUEST, OPCODES[multi? ? :setq : :set], key.bytesize, 8, 0, 0, value.bytesize + key.bytesize + 8, 0, 0, flags, ttl, key, value].pack(FORMAT[:set])
|
153
153
|
write(req)
|
@@ -155,7 +155,7 @@ module Dalli
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def add(key, value, ttl, cas, options)
|
158
|
-
(value, flags) = serialize(value, options)
|
158
|
+
(value, flags) = serialize(key, value, options)
|
159
159
|
|
160
160
|
req = [REQUEST, OPCODES[multi? ? :addq : :add], key.bytesize, 8, 0, 0, value.bytesize + key.bytesize + 8, 0, cas, flags, ttl, key, value].pack(FORMAT[:add])
|
161
161
|
write(req)
|
@@ -163,7 +163,7 @@ module Dalli
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def replace(key, value, ttl, options)
|
166
|
-
(value, flags) = serialize(value, options)
|
166
|
+
(value, flags) = serialize(key, value, options)
|
167
167
|
req = [REQUEST, OPCODES[multi? ? :replaceq : :replace], key.bytesize, 8, 0, 0, value.bytesize + key.bytesize + 8, 0, 0, flags, ttl, key, value].pack(FORMAT[:replace])
|
168
168
|
write(req)
|
169
169
|
generic_response unless multi?
|
@@ -249,7 +249,7 @@ module Dalli
|
|
249
249
|
FLAG_MARSHALLED = 0x1
|
250
250
|
FLAG_COMPRESSED = 0x2
|
251
251
|
|
252
|
-
def serialize(value, options=nil)
|
252
|
+
def serialize(key, value, options=nil)
|
253
253
|
marshalled = false
|
254
254
|
value = unless options && options[:raw]
|
255
255
|
marshalled = true
|
@@ -262,7 +262,7 @@ module Dalli
|
|
262
262
|
value = Zlib::Deflate.deflate(value)
|
263
263
|
compressed = true
|
264
264
|
end
|
265
|
-
raise Dalli::DalliError, "Value too large, memcached can only store #{@options[:value_max_bytes]}
|
265
|
+
raise Dalli::DalliError, "Value too large, memcached can only store #{@options[:value_max_bytes]} bytes per key [key: #{key}, size: #{value.bytesize}]" if value.bytesize > @options[:value_max_bytes]
|
266
266
|
flags = 0
|
267
267
|
flags |= FLAG_COMPRESSED if compressed
|
268
268
|
flags |= FLAG_MARSHALLED if marshalled
|
data/lib/dalli/version.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCompatibility < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
require 'dalli/memcache-client'
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'dalli in memcache-client mode' do
|
10
|
+
|
11
|
+
should 'handle old raw flag to set/add/replace' do
|
12
|
+
memcached do |dc|
|
13
|
+
assert_equal "STORED\r\n", dc.set('abc', 123, 5, true)
|
14
|
+
assert_equal '123', dc.get('abc', true)
|
15
|
+
|
16
|
+
assert_equal "NOT_STORED\r\n", dc.add('abc', 456, 5, true)
|
17
|
+
assert_equal '123', dc.get('abc', true)
|
18
|
+
|
19
|
+
assert_equal "STORED\r\n", dc.replace('abc', 456, 5, false)
|
20
|
+
assert_equal 456, dc.get('abc', false)
|
21
|
+
|
22
|
+
assert_equal "DELETED\r\n", dc.delete('abc')
|
23
|
+
assert_equal "NOT_DELETED\r\n", dc.delete('abc')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def teardown
|
30
|
+
Dalli::Client.compatibility_mode = false
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/test_session_store.rb
CHANGED
@@ -182,19 +182,44 @@ class TestSessionStore < ActionController::IntegrationTest
|
|
182
182
|
assert_not_equal session_id, cookies['_session_id']
|
183
183
|
end
|
184
184
|
end
|
185
|
+
|
186
|
+
def test_expire_after
|
187
|
+
with_test_route_set(:expire_after => 1) do
|
188
|
+
get '/set_session_value'
|
189
|
+
assert_match /expires/, @response.headers['Set-Cookie']
|
190
|
+
|
191
|
+
sleep(1)
|
192
|
+
|
193
|
+
get '/get_session_value'
|
194
|
+
assert_equal 'foo: nil', response.body
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_expires_in
|
199
|
+
with_test_route_set(:expires_in => 1) do
|
200
|
+
get '/set_session_value'
|
201
|
+
assert_no_match /expires/, @response.headers['Set-Cookie']
|
202
|
+
|
203
|
+
sleep(1)
|
204
|
+
|
205
|
+
get '/get_session_value'
|
206
|
+
assert_equal 'foo: nil', response.body
|
207
|
+
end
|
208
|
+
end
|
185
209
|
rescue LoadError, RuntimeError
|
186
210
|
$stderr.puts "Skipping TestSessionStore tests. Start memcached and try again."
|
187
211
|
end
|
188
212
|
|
189
213
|
private
|
190
|
-
def with_test_route_set
|
214
|
+
def with_test_route_set(options = {})
|
215
|
+
options = {:key => '_session_id'}.merge(options)
|
191
216
|
with_routing do |set|
|
192
217
|
set.draw do |map|
|
193
218
|
match ':action', :to => ::TestSessionStore::TestController
|
194
219
|
end
|
195
220
|
|
196
221
|
@app = self.class.build_app(set) do |middleware|
|
197
|
-
middleware.use ActionDispatch::Session::DalliStore,
|
222
|
+
middleware.use ActionDispatch::Session::DalliStore, options
|
198
223
|
middleware.delete "ActionDispatch::ShowExceptions"
|
199
224
|
end
|
200
225
|
|
@@ -202,4 +227,4 @@ class TestSessionStore < ActionController::IntegrationTest
|
|
202
227
|
end
|
203
228
|
end
|
204
229
|
end
|
205
|
-
end
|
230
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 2
|
9
|
+
version: 1.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Perham
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-02-03 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -87,6 +87,8 @@ files:
|
|
87
87
|
- lib/active_support/cache/dalli_store.rb
|
88
88
|
- lib/active_support/cache/dalli_store23.rb
|
89
89
|
- lib/dalli/client.rb
|
90
|
+
- lib/dalli/compatibility.rb
|
91
|
+
- lib/dalli/memcache-client.rb
|
90
92
|
- lib/dalli/options.rb
|
91
93
|
- lib/dalli/ring.rb
|
92
94
|
- lib/dalli/server.rb
|
@@ -106,6 +108,7 @@ files:
|
|
106
108
|
- test/helper.rb
|
107
109
|
- test/memcached_mock.rb
|
108
110
|
- test/test_active_support.rb
|
111
|
+
- test/test_compatibility.rb
|
109
112
|
- test/test_dalli.rb
|
110
113
|
- test/test_encoding.rb
|
111
114
|
- test/test_failover.rb
|
@@ -151,6 +154,7 @@ test_files:
|
|
151
154
|
- test/helper.rb
|
152
155
|
- test/memcached_mock.rb
|
153
156
|
- test/test_active_support.rb
|
157
|
+
- test/test_compatibility.rb
|
154
158
|
- test/test_dalli.rb
|
155
159
|
- test/test_encoding.rb
|
156
160
|
- test/test_failover.rb
|