alexpelan
alexpelan

Reputation: 35

Rails / Ajax - Showing progress bar for long running foreground process

I'm working on an app where a user logs in with twitter and right after they have authenticated we do a lot of processing and loading of tweets. This can easily take 5-10 seconds, so I'd like to have a progress bar that tells them how many tweets we've loaded and how many are left to load. A good example of what I'm trying to accomplish is Hipmunk's flight search.

I'm trying to do this by kicking off two AJAX requests on page load. The first one runs the controller method that talks to the twitter API (the long running process), and then the second one runs a different controller method every second - ideally I would want it to poll the status of the first request, stored in the session variable.

What I'm seeing in practice is that the first request blocks until it is complete, and then the second request starts running.

1) Am I doing something wrong? Do AJAX requests block? Is this rails specific? If so, I'd love any material that explains why.
2) If I can't do it this way, is there a different pattern I should be using? My thought is I could change the long running request to only handle say, 200 tweets at a time, and update the status to the client as well, but that seems like it would involve a lot of passing information back and forth between the server and the client.

Upvotes: 1

Views: 1786

Answers (1)

Richard Peck
Richard Peck

Reputation: 76784

I think the pattern is ok but could be improved:


Block

As far as I know, Ajax requests do not "block", as its their nature to be Asynchronous (the name AJAX stands for Asynchronous Javascript And XML)

There are various resources (including this great post from CSS-tricks) which explain how to call AJAX multiple times on a page, which suggests to me it's not uncommon to do this

The only way this would be a problem is if you use the sync: true argument in the ajax call. This will basically prevent any other process from happening (and freezes the browser) until it's complete


System

I'd look at the problem at a systemic level

You're trying to import a number of tweets? Twitter's API is throttled, which means it doesn't lend itself to "on demand" requests

This could be better suited to a background job, which will then update your front-end using a websocket interface, using the ActionController::Live functionality of Rails, or similar:

Mix this module in to your controller, and all actions in that controller will be able to stream data to the client as it's written.


Background

In terms of the backend job, it's entirely dependent on what you want to achieve. If you can split it up into manageable blocks, you might get away with a controller/action call; whilst if you're trying to import large amounts of data from Twitter, you may be better populating your own model over a longer period of time (typically hours), using Redis as a queuing system

Progress Bar

The progress bar would be quite simple if you're able to implement a websocket & manage your data collection. You'd basically be able to send some data (typically the number of how much data has been processed) to the controller/action that your websock is litening to; allowing you to append any updates on the front-end with JS

Upvotes: 1

Related Questions