Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show progress during a long Ajax call

I have a simple web site (http://www.kousenit.com/twitterfollowervalue) that computes a quantity based on a person's Twitter followers. Since the Twitter API only returns followers 100 at a time, a complete process may involve lots of calls.

At the moment, I have an Ajax call to a method that runs the Twitter loop. The method looks like (Groovy):

def updateFollowers() {
    def slurper = new XmlSlurper()
    followers = []
    def next = -1
    while (next) {
        def url = "http://api.twitter.com/1/statuses/followers.xml?id=$id&cursor=$next"
        def response = slurper.parse(url)
        response.users.user.each { u ->
           followers << new TwitterUser(... process data ...)
        }
        next = response.next_cursor.toBigInteger()
    }
    return followers
}

This is invoked from a controller called renderTTFV.groovy. I call the controller via an Ajax call using the prototype library:

On my web page, in the header section (JavaScript):

function displayTTFV() {
    new Ajax.Updater('ttfv','renderTTFV.groovy', {});
}

and there's a div in the body of the page that updates when the call is complete.

Everything is working, but the updateFollowers method can take a fair amount of time. Is there some way I could return a progress value? For example, I'd like to update the web page on every iteration. I know ahead of time how many iterations there will be. I just can't figure out a way to update the page in the middle of that loop.

Any suggestions would be appreciated.

like image 523
kousen Avatar asked Apr 03 '10 22:04

kousen


1 Answers

For more-or-less-accurate progress reporting you have two alternatives:

  • Keep the server telling you its progress
  • Keep the client (browser) asking the server about its progress

Keeping the server telling you the progress would be kind of easy to implement. You can, instead of calling the Ajax.Updater, create an iframe element and modify the server to, for each iteration, dump a response with some javascript to trigger showing the progress on the browser, and to flush that response. Like that, the browser will execute the javascript and keep waiting until the response finishes, so the user will see the progress indicator moving up until everything's completed.

Other approaches are available for the server to tell you about the operation's progress. You can Bing/Google about Comet servers.

As for getting the browser to periodically ask about the operation's progress, you can either return some token to the browser for each iteration that the browser would check to see if it's the final result or if it should pass it on to the server so the server keeps hitting twitter for the next result set, or somehow keep a state (if you have session state support, that might do it) in your server that is updated in each iteration and that can be polled on a separate request.

I hope the suggestions help.

like image 190
Miguel Ventura Avatar answered Oct 21 '22 07:10

Miguel Ventura