Support for processing after the response has been transmitted?

Hi,

Is there any interest in allowing controller methods to do
post-response processing? This would be useful where some
time-consuming statistic or index processing should be done
after the response has been sent so as not to delay a response
that does not depend on that processing.

This could be implemented by allowing the action method to
yield to the process method which in turn yields to a
dispatcher CGI out call. The yield could either be called
explicitly or done by a call to render.

If there's a concern about tying up Web handlers, what sort
of limit should be placed on the processing time before one
should instead set up an asynchronous task to do such work?

I'm pretty sure you can just do the following:

def show
   # fetch me something to render
   render
   # do some long operation
end

-- tim

Yes, you can do that, but it won't render until the method returns.

A pretty simple way to accomplish this is to use BackgrounDRb to do the work in another process.

What you mean to say is, no, you shouldn't do it that way :slight_smile: since
it'll tie up the controller.

You could fork off a process and detach it if you're not interested in
the results. Take a look at the daemonize library.

Also check out this gratuitous self-link at
http://blog.caboo.se/articles/2006/10/14/premcache-caching-and-precaching-with-memcached
if that's the sort of thing that floats your boat.

Courtenay
http://blog.caboo.se

doh! I do this in multiple places already... silly me. Best to shut my trap until the new years detox.

Happy New Years all. A big thankyou to all those who have contributed to Rails in 2006!

-- tim

Courtenay wrote:

What you mean to say is, no, you shouldn't do it that way :slight_smile: since
it'll tie up the controller.

I just thought that for something that doesn't take too long,
the simplicity of just adding a "yield" to the action code is
attractive.

You could fork off a process and detach it if you're not interested in
the results. Take a look at the daemonize library.

Thanks Courtenay. This would be easier to manage than a pipe to
a DRb processor. Such a forked process would however have to have
access to the whole Rails environment, so I would either have to
fork a script/runner (too slow), or have the forked process make a
local controller call, which would tie up the request handlers even
more unless you could set the web-server to serve such requests
with a lower priority.

The forked process *does* have access to the whole rails environment,
and it's instant, but you have to re-connect to the DB and re-open any
files (like logs), if I recall correctly. (We were looking at this
method as a fast way of spawning listeners, but it got too tricky)

It would likely be trivial to move the time-intensive code to its own
class and just call that in the fork.

The forked process *does* have access to the whole rails environment,
and it's instant, but you have to re-connect to the DB and re-open any
files (like logs), if I recall correctly. (We were looking at this
method as a fast way of spawning listeners, but it got too tricky)

It would likely be trivial to move the time-intensive code to its own
class and just call that in the fork.

I've found it much *much* easier to start a drb worker like background
drb does, than try to deal with forking the rails process. If you use
a work queue (rinda, or model based) and you can shift expensive
processing into another process relatively smoothly.