mob-dalli 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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