dalli 1.1.4 → 2.7.11
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.
- checksums.yaml +7 -0
- data/Gemfile +8 -4
- data/History.md +267 -1
- data/LICENSE +1 -1
- data/README.md +129 -85
- data/lib/action_dispatch/middleware/session/dalli_store.rb +7 -1
- data/lib/active_support/cache/dalli_store.rb +361 -104
- data/lib/dalli.rb +9 -7
- data/lib/dalli/cas/client.rb +59 -0
- data/lib/dalli/client.rb +298 -103
- data/lib/dalli/compressor.rb +30 -0
- data/lib/dalli/options.rb +19 -0
- data/lib/dalli/railtie.rb +8 -0
- data/lib/dalli/ring.rb +59 -22
- data/lib/dalli/server.rb +346 -125
- data/lib/dalli/socket.rb +105 -105
- data/lib/dalli/version.rb +2 -1
- data/lib/rack/session/dalli.rb +156 -22
- metadata +29 -104
- data/Performance.md +0 -85
- data/Rakefile +0 -39
- data/Upgrade.md +0 -45
- data/dalli.gemspec +0 -31
- data/lib/active_support/cache/dalli_store23.rb +0 -172
- data/lib/dalli/compatibility.rb +0 -52
- data/lib/dalli/memcache-client.rb +0 -1
- data/test/abstract_unit.rb +0 -282
- data/test/benchmark_test.rb +0 -170
- data/test/helper.rb +0 -39
- data/test/memcached_mock.rb +0 -126
- data/test/test_active_support.rb +0 -201
- data/test/test_compatibility.rb +0 -33
- data/test/test_dalli.rb +0 -450
- data/test/test_encoding.rb +0 -43
- data/test/test_failover.rb +0 -107
- data/test/test_network.rb +0 -54
- data/test/test_ring.rb +0 -85
- data/test/test_sasl.rb +0 -83
- data/test/test_session_store.rb +0 -225
- data/test/test_synchrony.rb +0 -175
data/lib/dalli/compatibility.rb
DELETED
@@ -1,52 +0,0 @@
|
|
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
|
@@ -1 +0,0 @@
|
|
1
|
-
Dalli::Client.compatibility_mode = true
|
data/test/abstract_unit.rb
DELETED
@@ -1,282 +0,0 @@
|
|
1
|
-
# Used to test the full Rails stack.
|
2
|
-
# Stolen from the Rails 3.0 source.
|
3
|
-
# Needed for the session store tests.
|
4
|
-
require 'active_support/core_ext/kernel/reporting'
|
5
|
-
require 'active_support/core_ext/string/encoding'
|
6
|
-
if "ruby".encoding_aware?
|
7
|
-
# These are the normal settings that will be set up by Railties
|
8
|
-
# TODO: Have these tests support other combinations of these values
|
9
|
-
silence_warnings do
|
10
|
-
Encoding.default_internal = "UTF-8"
|
11
|
-
Encoding.default_external = "UTF-8"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'test/unit'
|
16
|
-
require 'abstract_controller'
|
17
|
-
require 'action_controller'
|
18
|
-
require 'action_view'
|
19
|
-
require 'action_dispatch'
|
20
|
-
require 'active_support/dependencies'
|
21
|
-
require 'action_controller/caching'
|
22
|
-
require 'action_controller/caching/sweeping'
|
23
|
-
|
24
|
-
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
|
25
|
-
|
26
|
-
module Rails
|
27
|
-
def self.logger
|
28
|
-
@logger ||= begin
|
29
|
-
l = Logger.new(STDOUT)
|
30
|
-
l.level = Logger::INFO; l
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Monkey patch the old routes initialization to be silenced.
|
36
|
-
class ActionDispatch::Routing::DeprecatedMapper
|
37
|
-
def initialize_with_silencer(*args)
|
38
|
-
ActiveSupport::Deprecation.silence { initialize_without_silencer(*args) }
|
39
|
-
end
|
40
|
-
alias_method_chain :initialize, :silencer
|
41
|
-
end
|
42
|
-
|
43
|
-
ActiveSupport::Dependencies.hook!
|
44
|
-
|
45
|
-
# Show backtraces for deprecated behavior for quicker cleanup.
|
46
|
-
ActiveSupport::Deprecation.debug = true
|
47
|
-
|
48
|
-
ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
|
49
|
-
|
50
|
-
module RackTestUtils
|
51
|
-
def body_to_string(body)
|
52
|
-
if body.respond_to?(:each)
|
53
|
-
str = ""
|
54
|
-
body.each {|s| str << s }
|
55
|
-
str
|
56
|
-
else
|
57
|
-
body
|
58
|
-
end
|
59
|
-
end
|
60
|
-
extend self
|
61
|
-
end
|
62
|
-
|
63
|
-
module SetupOnce
|
64
|
-
extend ActiveSupport::Concern
|
65
|
-
|
66
|
-
included do
|
67
|
-
cattr_accessor :setup_once_block
|
68
|
-
self.setup_once_block = nil
|
69
|
-
|
70
|
-
setup :run_setup_once
|
71
|
-
end
|
72
|
-
|
73
|
-
module ClassMethods
|
74
|
-
def setup_once(&block)
|
75
|
-
self.setup_once_block = block
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
def run_setup_once
|
81
|
-
if self.setup_once_block
|
82
|
-
self.setup_once_block.call
|
83
|
-
self.setup_once_block = nil
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
|
89
|
-
|
90
|
-
module ActiveSupport
|
91
|
-
class TestCase
|
92
|
-
include SetupOnce
|
93
|
-
# Hold off drawing routes until all the possible controller classes
|
94
|
-
# have been loaded.
|
95
|
-
setup_once do
|
96
|
-
SharedTestRoutes.draw do
|
97
|
-
match ':controller(/:action(/:id))'
|
98
|
-
end
|
99
|
-
|
100
|
-
ActionController::IntegrationTest.app.routes.draw do
|
101
|
-
match ':controller(/:action(/:id))'
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
class RoutedRackApp
|
108
|
-
attr_reader :routes
|
109
|
-
|
110
|
-
def initialize(routes, &blk)
|
111
|
-
@routes = routes
|
112
|
-
@stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
|
113
|
-
end
|
114
|
-
|
115
|
-
def call(env)
|
116
|
-
@stack.call(env)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
class BasicController
|
121
|
-
attr_accessor :request
|
122
|
-
|
123
|
-
def config
|
124
|
-
@config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
|
125
|
-
# VIEW TODO: View tests should not require a controller
|
126
|
-
public_dir = File.expand_path("../fixtures/public", __FILE__)
|
127
|
-
config.assets_dir = public_dir
|
128
|
-
config.javascripts_dir = "#{public_dir}/javascripts"
|
129
|
-
config.stylesheets_dir = "#{public_dir}/stylesheets"
|
130
|
-
config
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
|
136
|
-
setup do
|
137
|
-
@routes = SharedTestRoutes
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
class ActionController::IntegrationTest < ActiveSupport::TestCase
|
142
|
-
def self.build_app(routes = nil)
|
143
|
-
RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
|
144
|
-
middleware.use "ActionDispatch::ShowExceptions"
|
145
|
-
middleware.use "ActionDispatch::Callbacks"
|
146
|
-
middleware.use "ActionDispatch::ParamsParser"
|
147
|
-
middleware.use "ActionDispatch::Cookies"
|
148
|
-
middleware.use "ActionDispatch::Flash"
|
149
|
-
middleware.use "ActionDispatch::Head"
|
150
|
-
yield(middleware) if block_given?
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
self.app = build_app
|
155
|
-
|
156
|
-
# Stub Rails dispatcher so it does not get controller references and
|
157
|
-
# simply return the controller#action as Rack::Body.
|
158
|
-
class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
|
159
|
-
protected
|
160
|
-
def controller_reference(controller_param)
|
161
|
-
controller_param
|
162
|
-
end
|
163
|
-
|
164
|
-
def dispatch(controller, action, env)
|
165
|
-
[200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.stub_controllers
|
170
|
-
old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
|
171
|
-
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
|
172
|
-
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
|
173
|
-
yield ActionDispatch::Routing::RouteSet.new
|
174
|
-
ensure
|
175
|
-
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
|
176
|
-
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
|
177
|
-
end
|
178
|
-
|
179
|
-
def with_routing(&block)
|
180
|
-
temporary_routes = ActionDispatch::Routing::RouteSet.new
|
181
|
-
old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
|
182
|
-
old_routes = SharedTestRoutes
|
183
|
-
silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
|
184
|
-
|
185
|
-
yield temporary_routes
|
186
|
-
ensure
|
187
|
-
self.class.app = old_app
|
188
|
-
silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
|
189
|
-
end
|
190
|
-
|
191
|
-
def with_autoload_path(path)
|
192
|
-
path = File.join(File.dirname(__FILE__), "fixtures", path)
|
193
|
-
if ActiveSupport::Dependencies.autoload_paths.include?(path)
|
194
|
-
yield
|
195
|
-
else
|
196
|
-
begin
|
197
|
-
ActiveSupport::Dependencies.autoload_paths << path
|
198
|
-
yield
|
199
|
-
ensure
|
200
|
-
ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
|
201
|
-
ActiveSupport::Dependencies.clear
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
# Temporary base class
|
208
|
-
class Rack::TestCase < ActionController::IntegrationTest
|
209
|
-
def self.testing(klass = nil)
|
210
|
-
if klass
|
211
|
-
@testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
|
212
|
-
else
|
213
|
-
@testing
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def get(thing, *args)
|
218
|
-
if thing.is_a?(Symbol)
|
219
|
-
super("#{self.class.testing}/#{thing}", *args)
|
220
|
-
else
|
221
|
-
super
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def assert_body(body)
|
226
|
-
assert_equal body, Array.wrap(response.body).join
|
227
|
-
end
|
228
|
-
|
229
|
-
def assert_status(code)
|
230
|
-
assert_equal code, response.status
|
231
|
-
end
|
232
|
-
|
233
|
-
def assert_response(body, status = 200, headers = {})
|
234
|
-
assert_body body
|
235
|
-
assert_status status
|
236
|
-
headers.each do |header, value|
|
237
|
-
assert_header header, value
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def assert_content_type(type)
|
242
|
-
assert_equal type, response.headers["Content-Type"]
|
243
|
-
end
|
244
|
-
|
245
|
-
def assert_header(name, value)
|
246
|
-
assert_equal value, response.headers[name]
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
class ActionController::Base
|
251
|
-
def self.test_routes(&block)
|
252
|
-
routes = ActionDispatch::Routing::RouteSet.new
|
253
|
-
routes.draw(&block)
|
254
|
-
include routes.url_helpers
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
class ::ApplicationController < ActionController::Base
|
259
|
-
end
|
260
|
-
|
261
|
-
module ActionController
|
262
|
-
class Base
|
263
|
-
include ActionController::Testing
|
264
|
-
end
|
265
|
-
|
266
|
-
Base.view_paths = []
|
267
|
-
|
268
|
-
class TestCase
|
269
|
-
include ActionDispatch::TestProcess
|
270
|
-
|
271
|
-
setup do
|
272
|
-
@routes = SharedTestRoutes
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
# This stub emulates the Railtie including the URL helpers from a Rails application
|
278
|
-
module ActionController
|
279
|
-
class Base
|
280
|
-
include SharedTestRoutes.url_helpers
|
281
|
-
end
|
282
|
-
end
|
data/test/benchmark_test.rb
DELETED
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
class TestBenchmark < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def setup
|
7
|
-
puts "Testing #{Dalli::VERSION} with #{RUBY_DESCRIPTION}"
|
8
|
-
# We'll use a simple @value to try to avoid spending time in Marshal,
|
9
|
-
# which is a constant penalty that both clients have to pay
|
10
|
-
@value = []
|
11
|
-
@marshalled = Marshal.dump(@value)
|
12
|
-
|
13
|
-
@servers = ['127.0.0.1:19122', 'localhost:19122']
|
14
|
-
@key1 = "Short"
|
15
|
-
@key2 = "Sym1-2-3::45"*8
|
16
|
-
@key3 = "Long"*40
|
17
|
-
@key4 = "Medium"*8
|
18
|
-
# 5 and 6 are only used for multiget miss test
|
19
|
-
@key5 = "Medium2"*8
|
20
|
-
@key6 = "Long3"*40
|
21
|
-
@counter = 'counter'
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_benchmark
|
25
|
-
memcached do
|
26
|
-
|
27
|
-
Benchmark.bm(31) do |x|
|
28
|
-
|
29
|
-
n = 2500
|
30
|
-
|
31
|
-
@m = Dalli::Client.new(@servers)
|
32
|
-
x.report("set:plain:dalli") do
|
33
|
-
n.times do
|
34
|
-
@m.set @key1, @marshalled, 0, :raw => true
|
35
|
-
@m.set @key2, @marshalled, 0, :raw => true
|
36
|
-
@m.set @key3, @marshalled, 0, :raw => true
|
37
|
-
@m.set @key1, @marshalled, 0, :raw => true
|
38
|
-
@m.set @key2, @marshalled, 0, :raw => true
|
39
|
-
@m.set @key3, @marshalled, 0, :raw => true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
@m = Dalli::Client.new(@servers)
|
44
|
-
x.report("setq:plain:dalli") do
|
45
|
-
@m.multi do
|
46
|
-
n.times do
|
47
|
-
@m.set @key1, @marshalled, 0, :raw => true
|
48
|
-
@m.set @key2, @marshalled, 0, :raw => true
|
49
|
-
@m.set @key3, @marshalled, 0, :raw => true
|
50
|
-
@m.set @key1, @marshalled, 0, :raw => true
|
51
|
-
@m.set @key2, @marshalled, 0, :raw => true
|
52
|
-
@m.set @key3, @marshalled, 0, :raw => true
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
@m = Dalli::Client.new(@servers)
|
58
|
-
x.report("set:ruby:dalli") do
|
59
|
-
n.times do
|
60
|
-
@m.set @key1, @value
|
61
|
-
@m.set @key2, @value
|
62
|
-
@m.set @key3, @value
|
63
|
-
@m.set @key1, @value
|
64
|
-
@m.set @key2, @value
|
65
|
-
@m.set @key3, @value
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
@m = Dalli::Client.new(@servers)
|
70
|
-
x.report("get:plain:dalli") do
|
71
|
-
n.times do
|
72
|
-
@m.get @key1, :raw => true
|
73
|
-
@m.get @key2, :raw => true
|
74
|
-
@m.get @key3, :raw => true
|
75
|
-
@m.get @key1, :raw => true
|
76
|
-
@m.get @key2, :raw => true
|
77
|
-
@m.get @key3, :raw => true
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
@m = Dalli::Client.new(@servers)
|
82
|
-
x.report("get:ruby:dalli") do
|
83
|
-
n.times do
|
84
|
-
@m.get @key1
|
85
|
-
@m.get @key2
|
86
|
-
@m.get @key3
|
87
|
-
@m.get @key1
|
88
|
-
@m.get @key2
|
89
|
-
@m.get @key3
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
@m = Dalli::Client.new(@servers)
|
94
|
-
x.report("multiget:ruby:dalli") do
|
95
|
-
n.times do
|
96
|
-
# We don't use the keys array because splat is slow
|
97
|
-
@m.get_multi @key1, @key2, @key3, @key4, @key5, @key6
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
@m = Dalli::Client.new(@servers)
|
102
|
-
x.report("missing:ruby:dalli") do
|
103
|
-
n.times do
|
104
|
-
begin @m.delete @key1; rescue; end
|
105
|
-
begin @m.get @key1; rescue; end
|
106
|
-
begin @m.delete @key2; rescue; end
|
107
|
-
begin @m.get @key2; rescue; end
|
108
|
-
begin @m.delete @key3; rescue; end
|
109
|
-
begin @m.get @key3; rescue; end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
@m = Dalli::Client.new(@servers)
|
114
|
-
x.report("mixed:ruby:dalli") do
|
115
|
-
n.times do
|
116
|
-
@m.set @key1, @value
|
117
|
-
@m.set @key2, @value
|
118
|
-
@m.set @key3, @value
|
119
|
-
@m.get @key1
|
120
|
-
@m.get @key2
|
121
|
-
@m.get @key3
|
122
|
-
@m.set @key1, @value
|
123
|
-
@m.get @key1
|
124
|
-
@m.set @key2, @value
|
125
|
-
@m.get @key2
|
126
|
-
@m.set @key3, @value
|
127
|
-
@m.get @key3
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
@m = Dalli::Client.new(@servers)
|
132
|
-
x.report("mixedq:ruby:dalli") do
|
133
|
-
@m.multi do
|
134
|
-
n.times do
|
135
|
-
@m.set @key1, @value
|
136
|
-
@m.set @key2, @value
|
137
|
-
@m.set @key3, @value
|
138
|
-
@m.get @key1
|
139
|
-
@m.get @key2
|
140
|
-
@m.get @key3
|
141
|
-
@m.set @key1, @value
|
142
|
-
@m.get @key1
|
143
|
-
@m.set @key2, @value
|
144
|
-
@m.replace @key2, @value
|
145
|
-
@m.delete @key3
|
146
|
-
@m.add @key3, @value
|
147
|
-
@m.get @key2
|
148
|
-
@m.set @key3, @value
|
149
|
-
@m.get @key3
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
@m = Dalli::Client.new(@servers)
|
155
|
-
x.report("incr:ruby:dalli") do
|
156
|
-
n.times do
|
157
|
-
@m.incr @counter, 1, 0, 1
|
158
|
-
end
|
159
|
-
n.times do
|
160
|
-
@m.decr @counter, 1
|
161
|
-
end
|
162
|
-
|
163
|
-
assert_equal 0, @m.incr(@counter, 0)
|
164
|
-
end
|
165
|
-
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
end
|
170
|
-
end
|