I am using discogs-wrapper gem to access some music information, but I noticed that during the api request the server stills, no other requests are served, with a behavior similar to the debugger function. I believe the actual request is triggered in the following part of the gem, when I call the function Discogs::Artist.find_by_name name.
Net::HTTP.new(uri.host).start do |http|
http.request(request)
end
Follows the log for two requests in two different browser (chrome and firefox), I first run the search for the artist “pink floyd” and then refreshed the root page in the other browser, this last simple request that usually takes milliseconds, during the api request takes as long as the request lasts.
Started GET "/artists/show?utf8=%E2%9C%93&artist_name=pink+floyd&commit=search" for 127.0.0.1 at 2012-01-21 18:03:52 +0000
Processing by ArtistsController#show as HTML
Parameters: {"utf8"=>"✓", "artist_name"=>"pink floyd", "commit"=>"search"}
get_artist(pink floyd)
get_artist(pink floyd) - ended in 26394ms
Rendered artists/_search_form.html.haml (4.3ms)
Rendered discogs/artist/releases/_release.html.haml (606.5ms)
Rendered artists/show.html.haml within layouts/application (1876.4ms)
Completed 200 OK in 28303ms (Views: 1907.8ms | ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2012-01-21 18:04:20 +0000
Processing by ApplicationController#show as HTML
Rendered artists/_search_form.html.haml (4.5ms)
Rendered application/show.html.haml within layouts/application (6.5ms)
Completed 200 OK in 23ms (Views: 22.0ms | ActiveRecord: 0.0ms)
How can I avoid the server to hang uselessly for a response that could take even more than 30 secs? – thanks
You don’t want to do anything in the request/response cycle that can hang like that. Ideally, all actions in your Rails app should return as fast as possible.
The common solution to this problem is to move the long-running code to a separate background job process. I would not attempt anything like forking or running multiple threads in a single rails process.
The two popular background processing solutions I would recommend at this time are:
Other solutions background job solutions exist, but these are the two most popular ones, IMO.
To give feedback to the user that a background job has completed, a couple of options come to mind.
Use AJAX to poll the server to see when the job is done. For resque, there are a number of plugins that can help accomplish this: https://github.com/quirkey/resque-status or https://github.com/idris/resque-progress for example. I think this is simple and appropriate if the job will finish relatively quickly. Also, I wouldn’t make the ajax call too frequently. It would depend on your server response times and load, but I wouldn’t do it any more frequently than a second or two. If your server is slow or heavily loaded, this polling will make it worse.
Use push technology. I’ve found Juggernaut to be super easy to use. When the job is complete, push the message to the client. The infrastructure to support this is considerably more complex, however. But it remove the load of polling from the rails server and push technology can be used to implement all kinds of other cool things 🙂