Newbie Q: XMLHttpRequest.send() and race conditions?

Discussion in 'Javascript' started by kj, Dec 21, 2006.

  1. kj

    kj Guest

    Hi. I'm new to programming with XMLHttpRequest and I'm unclear
    about how non-blocking requests are handled, and in particular
    about the question of the potential for race conditions. Suppose
    that I have a function like this one that gets called when, for
    example, the user clicks some button X:

    function handleButtonXClick() {
    var request = makeRequest();
    function handleResponse() {
    if ( request.readyState == 4 && request.status == 200 ) {
    // has its way with some Innocent Global Variables...
    }
    };
    request.onreadystatechange = handleResponse;
    var url = 'http://myurl.com/cgi/latestinfo';
    request.open( 'GET', url ); // non-blocking request, asynchronous response
    request.send();
    }

    My question is: if the user triggers two invocations of handleResponse
    in rapid succession, could the second invocation begin before the
    first one is finished? Or does the browser ensure that these two
    invocations are executed sequentially?

    Assuming that the browser allows both invocations to execute
    concurrently, does JavaScript provide any mechanism for locking
    shared resources, such as global variables?

    (I know that I could design the UI to prevent concurrent requests,
    e.g. by disabling button X until handleResponse finishes, but I
    would like to avoid this if I can.)

    Thanks!

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Dec 21, 2006
    #1
    1. Advertising

  2. kj

    webEater Guest

    kj schrieb:

    > Hi. I'm new to programming with XMLHttpRequest and I'm unclear
    > about how non-blocking requests are handled, and in particular
    > about the question of the potential for race conditions. Suppose
    > that I have a function like this one that gets called when, for
    > example, the user clicks some button X:
    >
    > function handleButtonXClick() {
    > var request = makeRequest();
    > function handleResponse() {
    > if ( request.readyState == 4 && request.status == 200 ) {
    > // has its way with some Innocent Global Variables...
    > }
    > };
    > request.onreadystatechange = handleResponse;
    > var url = 'http://myurl.com/cgi/latestinfo';
    > request.open( 'GET', url ); // non-blocking request, asynchronous response
    > request.send();
    > }
    >
    > My question is: if the user triggers two invocations of handleResponse
    > in rapid succession, could the second invocation begin before the
    > first one is finished? Or does the browser ensure that these two
    > invocations are executed sequentially?
    >
    > Assuming that the browser allows both invocations to execute
    > concurrently, does JavaScript provide any mechanism for locking
    > shared resources, such as global variables?
    >
    > (I know that I could design the UI to prevent concurrent requests,
    > e.g. by disabling button X until handleResponse finishes, but I
    > would like to avoid this if I can.)
    >
    > Thanks!
    >
    > kj
    >
    > --
    > NOTE: In my address everything before the first period is backwards;
    > and the last period, and everything after it, should be discarded.


    What you do will not work, you must set the 3rd param for open method
    in firefox, true means asynchronous, false means synchronous request,
    so use true (the A in Ajax)

    request.open( 'GET', url, true); // non-blocking request, asynchronous
    response
    request.send(null);

    param in send method must be null.

    Andi
     
    webEater, Dec 21, 2006
    #2
    1. Advertising

  3. kj

    kj Guest

    In <> "webEater" <> writes:

    >What you do will not work, you must set the 3rd param for open method
    >in firefox, true means asynchronous, false means synchronous request,
    >so use true (the A in Ajax)


    >request.open( 'GET', url, true); // non-blocking request, asynchronous
    >response
    >request.send(null);


    >param in send method must be null.


    Thanks, but those details were not the point of my question. The
    main question remains: can multiple invocations of the onreadystatechange
    handler happen concurrently, or does the browser make sure that
    they happen sequentially?

    Thanks,

    kj
    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Dec 21, 2006
    #3
  4. Hi,

    kj wrote:
    > Hi. I'm new to programming with XMLHttpRequest and I'm unclear
    > about how non-blocking requests are handled, and in particular
    > about the question of the potential for race conditions. Suppose
    > that I have a function like this one that gets called when, for
    > example, the user clicks some button X:
    >
    > function handleButtonXClick() {
    > var request = makeRequest();
    > function handleResponse() {
    > if ( request.readyState == 4 && request.status == 200 ) {
    > // has its way with some Innocent Global Variables...
    > }
    > };
    > request.onreadystatechange = handleResponse;
    > var url = 'http://myurl.com/cgi/latestinfo';
    > request.open( 'GET', url ); // non-blocking request, asynchronous response
    > request.send();
    > }
    >
    > My question is: if the user triggers two invocations of handleResponse
    > in rapid succession, could the second invocation begin before the
    > first one is finished? Or does the browser ensure that these two
    > invocations are executed sequentially?


    The invocation will be executed sequentially (JavaScript is single
    threaded), but the browser doesn't check if a request is currently
    active before sending a next one. That would be very inefficient, and
    would lose all the benefits of asynchrnous requests.

    If you need to make sure that a request ends before another is sent, you
    can either use synchronous calls (but they are blocking, so not a good
    idea), or use a "isRequestActive" variable, which prevents a new request
    being sent as long as the response didn't arrive. Set the variable to
    true before the "send" call, set it to false in "handleResponse" (also
    in error cases).

    Additionally, it might be a good idea to enclose your code in try/catch,
    and set the varable to false in the catch (so that a possible error
    doesn't prevent sending again.

    One more thing: The current HTTP stack implementation prevents more than
    2 connections being open concurrently from a give client to a given web
    server. So you have a maximum of 2 concurrent XmlHttpRequests to a given
    web server at any time (but that doesn't help you in your case, 2 being
    too much anyway ;-)


    > Assuming that the browser allows both invocations to execute
    > concurrently, does JavaScript provide any mechanism for locking
    > shared resources, such as global variables?


    No, such mechanism (lock) doesn't exist in JavaScript, as JavaScript is
    single threaded and doesn't need this. But requests sent asynchronously
    are a special case, and need an implementation as described above.

    > (I know that I could design the UI to prevent concurrent requests,
    > e.g. by disabling button X until handleResponse finishes, but I
    > would like to avoid this if I can.)


    That would be a good practice anyway (but doesn't prevent you from
    implementing a safeguard).

    >
    > Thanks!
    >
    > kj


    HTH,
    Laurent
    --
    Laurent Bugnion, GalaSoft
    Software engineering: http://www.galasoft-LB.ch
    PhotoAlbum: http://www.galasoft-LB.ch/pictures
    Support children in Calcutta: http://www.calcutta-espoir.ch
     
    Laurent Bugnion, Dec 22, 2006
    #4
  5. kj

    webEater Guest

    > What you do will not work, you must set the 3rd param for open method
    > in firefox, true means asynchronous, false means synchronous request,


    I quote myself, I answered your question - this is what I wanted to
    explain you, the third param makes the difference. Default is true.
     
    webEater, Dec 22, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. The Weiss Family

    race conditions/pulse width

    The Weiss Family, Oct 16, 2004, in forum: VHDL
    Replies:
    6
    Views:
    757
    Jim Lewis
    Oct 19, 2004
  2. Taras_96
    Replies:
    7
    Views:
    6,843
    Taras_96
    Apr 5, 2005
  3. Replies:
    2
    Views:
    1,200
  4. mars
    Replies:
    6
    Views:
    377
    Laurent Pointal
    Feb 7, 2007
  5. Larry Bates

    Drop folder and race conditions

    Larry Bates, Oct 9, 2007, in forum: Python
    Replies:
    1
    Views:
    294
    Steven D'Aprano
    Oct 9, 2007
Loading...

Share This Page