Move gaint lock into middleware

This commit is contained in:
Joshua Peek 2008-12-18 12:00:54 -06:00
parent 3ff6b00ee3
commit 2eb2ec9e63
6 changed files with 44 additions and 16 deletions

View File

@ -56,6 +56,7 @@ module ActionController
autoload :Integration, 'action_controller/integration'
autoload :IntegrationTest, 'action_controller/integration'
autoload :Layout, 'action_controller/layout'
autoload :Lock, 'action_controller/lock'
autoload :MiddlewareStack, 'action_controller/middleware_stack'
autoload :MimeResponds, 'action_controller/mime_responds'
autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes'

View File

@ -2,8 +2,6 @@ module ActionController
# Dispatches requests to the appropriate controller and takes care of
# reloading the app after each request when Dependencies.load? is true.
class Dispatcher
@@guard = Mutex.new
class << self
def define_dispatcher_callbacks(cache_classes)
unless cache_classes
@ -46,6 +44,7 @@ module ActionController
cattr_accessor :middleware
self.middleware = MiddlewareStack.new do |middleware|
middleware.use "ActionController::Lock", :if => lambda { !ActionController::Base.allow_concurrency }
middleware.use "ActionController::Failsafe"
middleware.use "ActionController::SessionManagement::Middleware"
end
@ -59,7 +58,7 @@ module ActionController
@app = @@middleware.build(lambda { |env| self.dup._call(env) })
end
def dispatch_unlocked
def dispatch
begin
run_callbacks :before_dispatch
handle_request
@ -70,16 +69,6 @@ module ActionController
end
end
def dispatch
if ActionController::Base.allow_concurrency
dispatch_unlocked
else
@@guard.synchronize do
dispatch_unlocked
end
end
end
# DEPRECATE: Remove CGI support
def dispatch_cgi(cgi, session_options)
CGIHandler.dispatch_cgi(self, cgi, @output)

View File

@ -0,0 +1,18 @@
module ActionController
class Lock
def initialize(app)
@app = app
@lock = Mutex.new
end
def call(env)
old_multithread = env["rack.multithread"]
env["rack.multithread"] = false
response = @lock.synchronize do
@app.call(env)
end
env["rack.multithread"] = old_multithread
response
end
end
end

View File

@ -10,10 +10,26 @@ module ActionController
@klass = klass.to_s.constantize
end
options = args.extract_options!
if options.has_key?(:if)
@conditional = options.delete(:if)
else
@conditional = true
end
args << options unless options.empty?
@args = args
@block = block
end
def active?
if @conditional.respond_to?(:call)
@conditional.call
else
@conditional
end
end
def ==(middleware)
case middleware
when Middleware
@ -50,8 +66,12 @@ module ActionController
push(middleware)
end
def active
find_all { |middleware| middleware.active? }
end
def build(app)
reverse.inject(app) { |a, e| e.build(a) }
active.reverse.inject(app) { |a, e| e.build(a) }
end
end
end

View File

@ -50,7 +50,7 @@ class DispatcherTest < Test::Unit::TestCase
end
def test_failsafe_response
Dispatcher.any_instance.expects(:dispatch_unlocked).raises('b00m')
Dispatcher.any_instance.expects(:dispatch).raises('b00m')
ActionController::Failsafe.any_instance.expects(:log_failsafe_exception)
assert_nothing_raised do

View File

@ -1,6 +1,6 @@
desc 'Prints out your Rack middleware stack'
task :middleware => :environment do
ActionController::Dispatcher.middleware.each do |middleware|
ActionController::Dispatcher.middleware.active.each do |middleware|
puts "use #{middleware.inspect}"
end
puts "run ActionController::Dispatcher.new"