views:

547

answers:

2

I occasionally have some long running AJAX requests in my Wicket application. When this occurs the application is largely unusable as subsequent AJAX requests are queued up to process synchronously after the current request. I would like the request to terminate after a period of time regardless of whether or not a response has been returned (I have a user requirement that if this occurs we should present the user an error message and continue). This presents two questions:

  1. Is there any way to specify a timeout that's specific to an AJAX or all AJAX request(s)?
  2. If not, is there any way to kill the current request?

I've looked through the wicket-ajax.js file and I don't see any mention of a request timeout whatsoever.

I've even gone so far as to try re-loading the page after some timeout on the client side, but unfortunately the server is still busy processing the original AJAX request and does not return until the AJAX request has finished processing.

Thanks!

+2  A: 

Failed solution: After a given setTimeout I kill the active transports and restart the channel, which handles everything on the client side. I avoided request conflicts by tying each to an ID and checking that against a global reference that increments each time a request is made and each time a request completes.

 function longRunningCallCheck(refId) {
    // make sure the reference id matches the global id.
    // this indicates that we are still processing the
    // long running ajax call.
    if(refId == id){
        // perform client processing here

        // kill all active transport layers
        var t = Wicket.Ajax.transports;
        for (var i = 0; i < t.length; ++i) {
            if (t[i].readyState != 0) {
                t[i].onreadystatechange = Wicket.emptyFunction;
                t[i].abort();
            }
        }

        // process the default channel
        Wicket.channelManager.done('0|s');
    }
 }

Unfortunately, this still left the PageMap blocked and any subsequent calls wait for the request to complete on the server side.

My solution at this point is to instead provide the user an option to logout using a BookmarkablePageLink (which instantiates a new page, thus not having contention on the PageMap). Definitely not optimal.

Any better solutions are more than welcome, but this is the best one I could come up with.

Michael Krauklis
+1 for recognizing and posting a failed attempt. If nothing else it's more knowledge.
Matt
don't know wether its helping (I am hacking with ajax + wicket at the moment): Wicket.Throttler(true) can help for the timeout (see wicket-autocomplete.js from wicket extension) and then you could try your luck again with AjaxLazyLoadPanel :-) for the background task (or see the progressbar from wicketstuff)
Karussell
+3  A: 

I think it won't help you to let the client 'cancel' the request. (However this could work.)

The point is that the server is busy processing a request that is not required anymore. If you want to timeout such operations you had to implement the timeout on the server side. If the operation takes too long, then the server aborts it and returns some error value as the result of the Ajax request.

Regarding your queuing problem: You may consider to use asynchronous requests in spite of synchronous ones. This means that the client first sends a request for starting the long running process. This request immediately returns. Then the client periodically polls the server and asks if the process has finished. Those poll requests also return immediately saying either that the process is still running or that it has finished with a certain result.

Wolfgang
Thanks Wolfgang. I should've mentioned that we are processing models asynchronously for calls we think might run long (reports, large datasets, etc), but we are trying to tackle the problem where occasionally and unexpectedly a request takes a long time for unforeseen reasons. Sometimes this is due to DB issues (re-indexing, poor query design, etc) and sometimes this is due to third party service requests taking longer than expected. Ideally we would encapsulate all of these calls asynchronously, but at this point in the software life-cycle that is just not feasible. Thanks for your input.
Michael Krauklis