Skip to content

Commit

Permalink
added support for easily rendering async responses
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Myles committed Jun 22, 2010
1 parent fba8ceb commit 9f12a24
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
42 changes: 42 additions & 0 deletions README.rdoc
Expand Up @@ -106,6 +106,48 @@ JSON:

render(:json, {:status => "ok", :message => "done"})

== Async Responses

You should never block EventMachine. If you're doing any kind of I/O in your controller action you need to render your response asynchronously:

class DemoController < Fastr::Controller
def fast_index
EM.add_timer(1) do
async_resp { render(:text, "fast_index\n") }
end
render_async
end

def slow_index
sleep(1)
render(:text, "slow_index\n")
end
end

Here's the difference:

$ ab -n 10 -c 10 "http://127.0.0.1:4444/demo/fast_index"
Concurrency Level: 10
Time taken for tests: 1.010 seconds
Requests per second: 9.90 [#/sec] (mean)

$ ab -n 10 -c 10 "http://127.0.0.1:4444/demo/slow_index"
Concurrency Level: 10
Time taken for tests: 10.011 seconds
Requests per second: 1.00 [#/sec] (mean)

If all your actions in a controller are async you can use an after_filter to make things cleaner:

class DemoController < Fastr::Controller
after_filter :render_async

def index
EM.add_timer(1) do
async_resp { render(:text, "fast_index\n") }
end
end
end

== Deferred Responses

fastr also lets you return a deferred response. This is useful if you want to chunk the response back to the client, or have a long running operation that you want to perform without blocking EventMachine.
Expand Down
1 change: 1 addition & 0 deletions lib/fastr.rb
Expand Up @@ -14,4 +14,5 @@ module Fastr
autoload :Plugin, "#{ROOT}/fastr/plugin"
autoload :Cookie, "#{ROOT}/fastr/cookie"
autoload :Filter, "#{ROOT}/fastr/filter"
autoload :Async, "#{ROOT}/fastr/async"
end
11 changes: 11 additions & 0 deletions lib/fastr/async.rb
@@ -0,0 +1,11 @@
module Fastr
module Async
def async_resp(&blk)
env['async.callback'].call(blk.call)
end

def render_async(resp=nil)
[-1, {}, []].freeze
end
end
end
1 change: 1 addition & 0 deletions lib/fastr/controller.rb
Expand Up @@ -59,6 +59,7 @@ class Controller
include Fastr::Deferrable
include Fastr::Cookie
include Fastr::Filter
include Fastr::Async

def self.inherited(kls)
kls.instance_eval('include Fastr::Log')
Expand Down

0 comments on commit 9f12a24

Please sign in to comment.