Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "simpler solution for event dispatching. no more defer stack"

This reverts commit 92166b2.
  • Loading branch information...
commit 3c89006e06dc180d36b1c0f5ec37aa0d2ee9489b 1 parent 92166b2
@joshbuddy joshbuddy authored
View
20 lib/goliath/api.rb
@@ -5,10 +5,6 @@
require 'goliath/rack'
require 'goliath/validation'
-class HttpRouter::Route
- attr_accessor :event_handler
-end
-
module Goliath
# All Goliath APIs subclass Goliath::API. All subclasses _must_ override the
# {#response} method.
@@ -187,21 +183,6 @@ def env
Thread.current[GOLIATH_ENV]
end
- # Accessor for the event handler for on_{body, close, header}
- #
- # @return [Goliath::Api, nil] The current handler for events
-
- def event_handler
- @event_handler ||= begin
- if self.class.maps?
- response = self.class.router.recognize(env)
- response.path.route.event_handler
- else
- self
- end
- end
- end
-
# The API will proxy missing calls to the env object if possible.
#
# The two entries in this example are equivalent as long as you are not
@@ -235,6 +216,7 @@ def respond_to_missing?(name, *)
# @return [Goliath::Connection::AsyncResponse] An async response.
def call(env)
begin
+ Thread.current[GOLIATH_ENV] = env
status, headers, body = response(env)
if status
View
9 lib/goliath/connection.rb
@@ -32,12 +32,13 @@ def post_init
env[CONFIG] = config
env[REMOTE_ADDR] = remote_address
+ env[ASYNC_HEADERS] = @api.method(:on_headers) if @api.respond_to? :on_headers
+ env[ASYNC_BODY] = @api.method(:on_body) if @api.respond_to? :on_body
+ env[ASYNC_CLOSE] = @api.method(:on_close) if @api.respond_to? :on_close
+
r = Goliath::Request.new(@app, self, env)
r.parse_header(h, @parser)
- env[ASYNC_HEADERS] = @api.event_handler.method(:on_headers) if @api.event_handler.respond_to? :on_headers
- env[ASYNC_BODY] = @api.event_handler.method(:on_body) if @api.event_handler.respond_to? :on_body
- env[ASYNC_CLOSE] = @api.event_handler.method(:on_close) if @api.event_handler.respond_to? :on_close
- r.dispatch_header(h)
+
@requests.push(r)
end
View
4 lib/goliath/env.rb
@@ -121,6 +121,10 @@ def respond_to?(name)
super
end
+ def defer_stack
+ @defer_stack ||= []
+ end
+
# The Goliath::Env will provide any of it's keys as a method. It will also provide
# any of the keys in the config object as methods. The methods will return
# the value of the key. If the key doesn't exist in either hash this will
View
39 lib/goliath/rack/builder.rb
@@ -13,6 +13,35 @@ def run(app)
original_run(app)
end
+ module MappingHandlers
+ include Constants
+ attr_reader :last_app
+
+ def defer
+ defer = EM::DefaultDeferrable.new
+ Thread.current[GOLIATH_ENV].defer_stack << defer
+ defer
+ end
+
+ def on_body(env, body)
+ defer.callback do |api|
+ api.on_body(env, body) if api.respond_to?(:on_body)
+ end
+ end
+
+ def on_headers(env, headers)
+ defer.callback do |api|
+ api.on_headers(env, headers) if api.respond_to?(:on_headers)
+ end
+ end
+
+ def on_close(env)
+ defer.callback do |api|
+ api.on_close(env) if api.respond_to?(:on_close)
+ end
+ end
+ end
+
# Builds the rack middleware chain for the given API
#
# @param klass [Class] The API class to build the middlewares for
@@ -24,18 +53,18 @@ def self.build(klass, api)
use(mw_klass, *args, &blk)
end
if klass.maps?
+ klass.instance_eval "include MappingHandlers", __FILE__, __LINE__
klass.maps.each do |path, route_klass, opts, blk|
blk ||= Proc.new {
run Builder.build(route_klass, route_klass.new)
}
- builder = Builder.new
- builder.instance_eval(&blk)
- route = klass.router.add(path, opts.dup)
- route.event_handler = builder.inner_app
- route.to {|env|
+ klass.router.add(path, opts.dup).to {|env|
+ builder = Builder.new
env['params'] ||= {}
env['params'].merge!(env['router.params']) if env['router.params']
builder.params = builder.retrieve_params(env)
+ builder.instance_eval(&blk)
+ env.defer_stack.each{ |defer| defer.succeed(builder.inner_app)}
builder.to_app.call(env)
}
end
View
2  lib/goliath/request.rb
@@ -70,9 +70,7 @@ def parse_header(h, parser)
@env[REQUEST_PATH] = parser.request_path
@env[PATH_INFO] = parser.request_path
@env[FRAGMENT] = parser.fragment
- end
- def dispatch_header(h)
begin
@env[ASYNC_HEADERS].call(@env, h) if @env[ASYNC_HEADERS]
rescue Exception => e
Please sign in to comment.
Something went wrong with that request. Please try again.