Merb: render_deferred and render_then_call
Following the post on
non blocking merb actions,
it's worth mentioning the
Merb::ControllerMixin
module, its
render_deferred
and
render_then_call
methods in particular.
render_deferred
accepts a block argument, a
proc
that will be called outside the dispatch
mutex
,
releasing the merb thread lock.
class MyController < Merb::Controller def hello render "hello" end def dont_wait_to_hello render_deferred { VerySlow.hello } end end
Calls to
/my_controller/hello
,
subsequent to requests to
/my_controller/dont_wait_to_hello
,
will not have to wait for the latter to complete before being served.
As an interesting caveat, because execution of the
proc
is outside merb's control, any exceptions raised in the block passed to
render_deferred
will not be rescued and redispatched, which suggests that custom error handling needs to be in place.
render_then_call
accepts two arguments, a string that will be returned immediately as a response to the client and a block to be called after the string has been returned.
class MyController < Merb::Controller def receive_order render_then_call("Your pizza is in the oven.") do bake_pizza deliver_pizza end end end
In this case, the specified message will be immediately returned, while the long running
proc
will be scheduled and executed by Mongrel, allowing orders to keep coming through a single application instance.