views:

73

answers:

1

I noticed that sometimes(randomly) my Mootools ajax request gets send twice. The second request succeeds right away but the first just keeps waiting indefinitely. I'm not sure if it's a bug in Mootools or something I've done.

This has been verified with firebug in firefox and developer console in chrome. I couldn't verify it in IE, but the symptoms are the same.

I actually managed to take a screenshot of firebug showing the problem: http://janipeltoniemi.net/ajax.png

On the right you see the request loop script I wrote for testing purposes. It just makes a request with a new id after the previous request has completed, so nothing fancy there. The final 2 lines in the console demonstrate the problem I'm having. As you can see, they both have the same response and the same id. The md5 hash is generated using md5(microtime(1)), so it should be different if these 2 actually were different requests with the same id.

The loop stops at that point because it it doesn't fire the onSuccess event when the last one completes. I'm guessing it would fire it when the other request gets completed, but that hasn't happened yet.

Any ideas what's happening here?

Almost forgot, I'm using Mootools 1.2.4

The code in the image:

r = new Request.HTML();
counter = 0;
//increments the counter and requests hello.php
go = function() {
  counter += 1;
  //The loop was too fast and producted some side effects when delay was not used
  r.get.delay( 10, r, [ 'templates/hello.php', { counter: counter } ] )
}
//Create an endless loop. When the request from go() is finished, call go()
r.addEvent( 'success', go );
//Start the endless loop
go();
A: 

this seems to do with recycling the old instance of the Request class before it's "ready" so the old request fires the onSuccess w/o the server closing up the connection where the client loses interest and restarts it, leaving firebug in a waiting state.

http://www.jsfiddle.net/dimitar/NF2jz/201/

var r = new Request.HTML({
    url: '/ajax_html_echo/',
    data: {'html': "hello"},
    method: 'post',
    update: 'target_div',
    onSuccess: function(response) {
        (function() {
            go(); // you can reproduce the bug by removing the delay wrap
        }).delay(1000);
    }
});

var counter = 0;

var go = function() {
    counter++;
    // despite of trying r.cancel(), it does not cancel, 
    // you can set onCancel to test this;
    r.cancel().setOptions({
        data: {html: "attempt " + counter}
    }).send();

};

go();

strictly speaking, if you run off of an anonymous function, you don't need to be recycling the old instance - or even save it.

what i would do is something like this (but probably refactored so it can be cancelled):

var counter = 0;
(function go() {
    counter++;
    // fresh instance after success / complete:
    new Request.HTML({
        url: '/ajax_html_echo/',
        data: {'html': "hello " + counter},
        method: 'post',
        update: 'target_div',
        onSuccess: function(response) {
            go();
        }
    }).send();
})();

http://www.jsfiddle.net/dimitar/NF2jz/202/ demoing last code, works fine and in a way that completes and does not interfere with each other.

Dimitar Christoff
It seems I failed to mention that in the original case the request instance isn't recycled, sorry about that. Also, it's not just a single case. I've been noticing this strange behavior here and there for a while now, but only recently I've started to see it as a problem.
Pichan
well - with the risk of sounding annoyed - for future reference, post your exact code / url or build a test case that successfully reproduces your problem for everyone to see. otherwise, you are just wasting everyone's time. good luck fixing, there is no problem with the Request class that I know of. look for duplicate events bound that will trigger the ajax.
Dimitar Christoff
Yeah, I know. I probably should've posted the original code, but it's really no different from the test case(apart from reusing the request instance) if you strip it down to bare bones. The posted code was used by me to quickly reproduce the problem(at times takes >1000 requests before appearing) and since it seemed to succesfully reproduce the problem, I didn't think any further.
Pichan
Still, I'm positive that in the original case the there is no interference to the request, at least by my code. First the request instance is created and right after that the request is sent. Apart from `onSuccess`, which only sets an image element's url from the response, the request instance isn't used anywhere else.
Pichan
when i say test case, i mean go to jsfiddle or mooshell and create it, similar to http://www.jsfiddle.net/dimitar/NF2jz/202/ and show us how it breaks (this one does not). use `data: {html: ""}` to simulate your desired response and see how you get on.
Dimitar Christoff
Funny, I thought I already posted a comment regarding jsfiddle. Anyway, I tried to run your code in jsfiddle, but one request took around 2 seconds to complete, so it doesn't help much since my own local tests could easily take over 1000 cycles to produce the error. I used your code to make a stand-alone test script that should run very rapidly on a local server. You can see it at http://gist.github.com/484409I couldn't make it break on chrome this time but FF jammed after 3000 cycles or so.
Pichan
jsfiddle does a delay on purpose to simulate network lag. as for gist, replace `onSuccess` with `onComplete` or add `onFailure` to handle the odd timeout/clientside issue.
Dimitar Christoff
I added `onFailure` and `onSuccess` to the gist(http://gist.github.com/484409). It seems that none of the events fire after the problem appears. I'm going to do a test run with the script on an idle pc to see if really is browser or OS related. I'll post the results tomorrow when I get back to work.
Pichan
Okay, I ran the tests on another computer over the night and they worked fine. Maybe I should've tried that before, but since the main reason for starting all this troubleshooting was misbehavior reported by my client, I just assumed the problem isn't just with my firefox. I need to look into this more, but I guess for now it's my own problem. Even though the problem remains unsolved, I'll accept your answer. Thanks for the insightful advice :)
Pichan
i never use onSuccess and always onComplete - its more reliable.
Dimitar Christoff