Simplify the action endpoint:

* Remove ActionEndpoint in favor of passing a block to MiddlewareStack
  * Always create a Request; the performance win of RackDelegation is around
    the response; the Request object hit is limited to a single object allocation
  * #dispatch takes a Request
This commit is contained in:
Carlhuda 2010-03-08 16:49:47 -08:00
parent 146a5305d5
commit 056042eb82
4 changed files with 17 additions and 31 deletions

View File

@ -34,7 +34,8 @@ module ActionController
# and response object available. You might wish to control the
# environment and response manually for performance reasons.
attr_internal :status, :headers, :content_type, :response
attr_internal :status, :headers, :content_type, :response, :request
delegate :session, :to => "@_request"
def initialize(*)
@_headers = {}
@ -66,8 +67,9 @@ module ActionController
end
# :api: private
def dispatch(name, env)
@_env = env
def dispatch(name, request)
@_request = request
@_env = request.env
@_env['action_controller.instance'] = self
process(name)
to_a
@ -78,26 +80,6 @@ module ActionController
response ? response.to_a : [status, headers, response_body]
end
class ActionEndpoint
@@endpoints = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } }
def self.for(controller, action, stack)
@@endpoints[controller][action][stack] ||= begin
endpoint = new(controller, action)
stack.build(endpoint)
end
end
def initialize(controller, action)
@controller, @action = controller, action
@_formats = [Mime::HTML]
end
def call(env)
@controller.new.dispatch(@action, env)
end
end
class_attribute :middleware_stack
self.middleware_stack = ActionDispatch::MiddlewareStack.new
@ -127,8 +109,10 @@ module ActionController
#
# ==== Returns
# Proc:: A rack application
def self.action(name)
ActionEndpoint.for(self, name, middleware_stack)
def self.action(name, klass = ActionDispatch::Request)
middleware_stack.build do |env|
new.dispatch(name, klass.new(env))
end
end
end
end

View File

@ -6,14 +6,11 @@ module ActionController
extend ActiveSupport::Concern
included do
delegate :session, :to => "@_request"
delegate :headers, :status=, :location=, :content_type=,
:status, :location, :content_type, :to => "@_response"
attr_internal :request
end
def dispatch(action, env)
@_request = ActionDispatch::Request.new(env)
def dispatch(action, request)
@_response = ActionDispatch::Response.new
@_response.request = request
super

View File

@ -6,7 +6,8 @@ module ActionController
end
def call(env)
@controller.build(@app).dispatch(:index, env)
request = ActionDispatch::Request.new(env)
@controller.build(@app).dispatch(:index, request)
end
end

View File

@ -122,7 +122,11 @@ module ActionDispatch
find_all { |middleware| middleware.active? }
end
def build(app)
def build(app = nil, &blk)
app ||= blk
raise "MiddlewareStack#build requires an app" unless app
active.reverse.inject(app) { |a, e| e.build(a) }
end
end