I have been looking into the possibility of backgrounding some jobs with EventMachine. In Sinatra this appears to work great but Rails 3 appears to execute all ticks before render开发者_开发问答ing a view.
When I run the following code under the thin webserver it behaves as expected. The first request returns immediately and the second request is waiting for the 3 second sleep call to finish. This is the expected behavior.
class EMSinatra < Sinatra::Base
get "/" do
EM.next_tick { sleep 3 }
"Hello"
end
end
Whereas in Rails 3 running I am trying to do the same thing: (running under thin)
class EmController < ApplicationController
def index
EM.next_tick {
sleep(3)
}
end
end
In Rails the sleep call happens before rendering the view to the browser. The result is that I am waiting for 3 seconds for the initial page to render.
Does anybody know why this is happening? I am not looking for comments on wether this is a good practice or not. I am simply experimenting. Throwing small tasks into the reactor loop seems like an interesting thing to look into. Why should the client have to wait if I am going to make some non-blocking http-requests?
Im not sure this is the answer you are looking for but i did some research on this before. Let me tell you a littlebit of background information: What we wanted to achieve was that rails already flushed parts of the template tree (e.g. the first part of the layout) even when the controller action is taking a long while to load. The effect of this is that the user already sees something in their browser while the webserver is still doing work. Ofcourse the main view has to wait with rendering because it probably needs data from the controller action.
This technique is also known as BigPipe and facebook wrote a nice blog about this: http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919
Anyway, after doing some research to achieve this for rails 3 i found this blog post made by Yehuda Katz. http://yehudakatz.com/2010/09/07/automatic-flushing-the-rails-3-1-plan/
So for now i think you really have to stick with the waiting for the controller
Using EM.defer instead of EM.next_tick causes the sleep to happen after the response is sent back.
精彩评论