mob-dalli 1.1.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.
@@ -0,0 +1,170 @@
1
+ begin
2
+ require 'kgio'
3
+ puts "Using kgio socket IO" if defined?($TESTING) && $TESTING
4
+
5
+ class Dalli::Server::KSocket < Kgio::Socket
6
+ attr_accessor :options
7
+
8
+ def kgio_wait_readable
9
+ IO.select([self], nil, nil, options[:timeout]) || raise(Timeout::Error, "IO timeout")
10
+ end
11
+
12
+ def kgio_wait_writable
13
+ IO.select(nil, [self], nil, options[:timeout]) || raise(Timeout::Error, "IO timeout")
14
+ end
15
+
16
+ def self.open(host, port, options = {})
17
+ addr = Socket.pack_sockaddr_in(port, host)
18
+ sock = start(addr)
19
+ sock.options = options
20
+ sock.kgio_wait_writable
21
+ sock
22
+ end
23
+
24
+ alias :write :kgio_write
25
+
26
+ def readfull(count)
27
+ value = ''
28
+ loop do
29
+ value << kgio_read!(count - value.bytesize)
30
+ break if value.bytesize == count
31
+ end
32
+ value
33
+ end
34
+
35
+ end
36
+
37
+
38
+
39
+ if ::Kgio.respond_to?(:wait_readable=)
40
+ ::Kgio.wait_readable = :kgio_wait_readable
41
+ ::Kgio.wait_writable = :kgio_wait_writable
42
+ end
43
+
44
+ rescue LoadError
45
+
46
+ puts "Using standard socket IO (#{RUBY_DESCRIPTION})" if defined?($TESTING) && $TESTING
47
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
48
+
49
+ class Dalli::Server::KSocket < TCPSocket
50
+ attr_accessor :options
51
+
52
+ def self.open(host, port, options = {})
53
+ sock = new(host, port)
54
+ sock.options = { :host => host, :port => port }.merge(options)
55
+ sock
56
+ end
57
+
58
+ def readfull(count)
59
+ value = ''
60
+ begin
61
+ loop do
62
+ value << read_nonblock(count - value.bytesize)
63
+ break if value.bytesize == count
64
+ end
65
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
66
+ if IO.select([self], nil, nil, options[:timeout])
67
+ retry
68
+ else
69
+ raise Timeout::Error, "IO timeout: #{options.inspect}"
70
+ end
71
+ end
72
+ value
73
+ end
74
+
75
+ end
76
+
77
+ else
78
+
79
+ class Dalli::Server::KSocket < Socket
80
+ attr_accessor :options
81
+
82
+ def self.open(host, port, options = {})
83
+ # All this ugly code to ensure proper Socket connect timeout
84
+ addr = Socket.getaddrinfo(host, nil)
85
+ sock = new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
86
+ sock.options = { :host => host, :port => port }.merge(options)
87
+ begin
88
+ sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
89
+ rescue Errno::EINPROGRESS
90
+ resp = IO.select(nil, [sock], nil, sock.options[:timeout])
91
+ begin
92
+ sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
93
+ rescue Errno::EISCONN
94
+ end
95
+ end
96
+ sock
97
+ end
98
+
99
+ def readfull(count)
100
+ value = ''
101
+ begin
102
+ loop do
103
+ value << sysread(count - value.bytesize)
104
+ break if value.bytesize == count
105
+ end
106
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
107
+ if IO.select([self], nil, nil, options[:timeout])
108
+ retry
109
+ else
110
+ raise Timeout::Error, "IO timeout: #{options.inspect}"
111
+ end
112
+ end
113
+ value
114
+ end
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+ begin
121
+ require 'em-synchrony'
122
+ puts "Defining alternate em-synchrony socket IO" if defined?($TESTING) && $TESTING
123
+
124
+ class Dalli::Server::AsyncSocket < EventMachine::Synchrony::TCPSocket
125
+ # XXX. need to somehow implement the timeout option.
126
+ # EM::Synchrony::TCPsocket does give you any timeouts. To implement it we'd have
127
+ # to change that class to take a timeout parameter that it would then set on
128
+ # the Deferrable objects it waits on.
129
+ attr_accessor :options
130
+
131
+ def self.open(host, port, options = {})
132
+ sock = new(host, port)
133
+ sock.options = { :host => host, :port => port }.merge(options)
134
+ sock
135
+ end
136
+
137
+ def readfull(count)
138
+ value = ''
139
+ loop do
140
+ value << read(count - value.bytesize)
141
+ break if value.bytesize == count
142
+ end
143
+ value
144
+ end
145
+
146
+ end
147
+
148
+ rescue LoadError
149
+ puts "Could not define alternate em-synchrony socket IO" if defined?($TESTING) && $TESTING
150
+ end
151
+
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
169
+ end
170
+ end
@@ -0,0 +1,3 @@
1
+ module Dalli
2
+ VERSION = '1.1.4'
3
+ end
@@ -0,0 +1,47 @@
1
+ require 'dalli/client'
2
+ require 'dalli/ring'
3
+ require 'dalli/server'
4
+ require 'dalli/socket'
5
+ require 'dalli/version'
6
+ require 'dalli/options'
7
+
8
+ unless ''.respond_to?(:bytesize)
9
+ class String
10
+ alias_method :bytesize, :size
11
+ end
12
+ end
13
+
14
+ module Dalli
15
+ # generic error
16
+ class DalliError < RuntimeError; end
17
+ # socket/server communication error
18
+ class NetworkError < DalliError; end
19
+ # no server available/alive error
20
+ class RingError < DalliError; end
21
+ # application error in marshalling
22
+ class MarshalError < DalliError; end
23
+
24
+ def self.logger
25
+ @logger ||= (rails_logger || default_logger)
26
+ end
27
+
28
+ def self.rails_logger
29
+ (defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
30
+ (defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:debug) && RAILS_DEFAULT_LOGGER)
31
+ end
32
+
33
+ def self.default_logger
34
+ require 'logger'
35
+ l = Logger.new(STDOUT)
36
+ l.level = Logger::INFO
37
+ l
38
+ end
39
+
40
+ def self.logger=(logger)
41
+ @logger = logger
42
+ end
43
+ end
44
+
45
+ if defined?(RAILS_VERSION) && RAILS_VERSION < '3'
46
+ raise Dalli::DalliError, "Dalli #{Dalli::VERSION} does not support Rails version < 3.0"
47
+ 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| !MemCache::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
@@ -0,0 +1,31 @@
1
+ require './lib/dalli/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{mob-dalli}
5
+ s.version = Dalli::VERSION
6
+
7
+ s.authors = ["Mike Perham", "Aaron Daniel"]
8
+ s.date = Time.now.utc.strftime("%Y-%m-%d")
9
+ s.description = %q{High performance memcached client for Ruby}
10
+ s.email = %q{mperham@gmail.com}
11
+ s.files = Dir.glob("lib/**/*") + [
12
+ "LICENSE",
13
+ "README.md",
14
+ "History.md",
15
+ "Rakefile",
16
+ "Gemfile",
17
+ "mob-dalli.gemspec",
18
+ "Performance.md",
19
+ "Upgrade.md",
20
+ ]
21
+ s.homepage = %q{http://github.com/amdtech/dalli}
22
+ s.rdoc_options = ["--charset=UTF-8"]
23
+ s.require_paths = ["lib"]
24
+ s.summary = %q{High performance memcached client for Ruby}
25
+ s.test_files = Dir.glob("test/**/*")
26
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
27
+ s.add_development_dependency(%q<mocha>, [">= 0"])
28
+ s.add_development_dependency(%q<rails>, [">= 3.0.0"])
29
+ s.add_development_dependency(%q<memcache-client>, [">= 1.8.5"])
30
+ end
31
+
@@ -0,0 +1,282 @@
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