Reputation: 614
I am face to face with the following situation.
A user clicks on a link in order to generate a text or XML. I have a method generateXMLfile
in my controller which reads data from a db table and creates a hash or array. After reading and creating are finished I send data using send_file
method.
The file generating process may take time between 5 and 25 seconds (huge data), so what I want to do is to display the "Please wait" message with waiting gif animation while the request is being processed, and display the success message upon successful completion.
I know how to implement similar operations such as, for example, a file upload using pure AJAX, but I don't know how to do it in Rails.
Has anyone dealt with the similar problem? What is the best practice or Rails way to perform this operation? Any suggestions or recommendations?
UPDATE:
def generateXMLfile
#lengthy operation
(1..100000000).each do
end
sample_string = "This is a sample string\ngenerated by generateXML method.\n\n Bye!"
send_data sample_string,
:type => 'charset=utf-8; header=present',
:disposition => "attachment; filename=sample.txt"
end
Upvotes: 0
Views: 96
Reputation: 3726
It's not a good idea to have 5-25 seconds requests. It can render your application unresponsive when multiple users start uploading files simultaneously. Or you can hit a timeout limit on your web server. You should use some background processing tool, here are some options:
Delayed job is the simplest one, Sidekiq and Resque are a little bit more complex and they require you to install Redis.
When background processing finishes you can use some Websocket-based tool to send a message to your frontend. Pusher (http://pusher.com/) is one of such tools.
Upvotes: 1
Reputation: 7366
You can bind call like this using UJS.
<%= link_to "send file",generateXMLfile_path, :remote => true, :id => "send_file" %>
$('#send_file').bind('ajax:beforeSend', function() {
$('#please wait').show();
});
$('#send_file').bind('ajax:complete', function() {
$('#please_wait').hide();
$('flash').show();
});
You can also use generateXMLfile.js.erb
for complete action.
Upvotes: 1