fade2black
fade2black

Reputation: 614

Lengthy operation in Ruby-on-Rails

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

Answers (2)

cthulhu
cthulhu

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

Nitin
Nitin

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

Related Questions