[whatwg] Thread to run Web Socket feedback from the protocol ?

Jonas Sicking jonas at sicking.cc
Fri Dec 4 14:30:02 PST 2009


On Fri, Dec 4, 2009 at 9:52 AM, Alexey Proskuryakov <ap at webkit.org> wrote:
>
> On 04.12.2009, at 4:12, Anne van Kesteren wrote:
>
>>> On the other hand, it can't possibly work like XMLHttpRequest - for
>>> whatever reason, the Web Sockets spec says that events are posted
>>> asynchronously. Maybe I'm not the last an only one to get confused by this
>>> difference from XMLHttpRequest events.
>>
>> XMLHttpRequest network events are "asynchronous" too.
>
>
> Looks like the spec says so now. Does any browser post XMLHttpRequest events
> asynchronously? This change in the spec is not harmless, as it seems to make
> readystatechange event pretty much useless.

Depends which events we are talking about. Events that are fired as a
result of network activity is inheritly asynchronous since network
events arrive asynchronously. For example "progress" events or "load"
events.

Other events must be synchronous, for example the "readystatechange"
event that is fired during the call to XMLHttpRequest.open, or the
"loadstart" event fired from XMLHttpRequest.send must be fired
synchronously.

However for the events that are fired as a result of network activity,
I see no reason to fire these events asynchronously from that code.
I.e. when a network request is finished, XMLHttpRequest takes several
actions:

* Sets readystate to 4
* Fires "readystatechange"
* Fires "load"
* Fires "loadend"
* Makes responseXML non-null

I see no reason to make these events be fired asynchronously *from the
code that takes all these actions*. In other words, I think the
XMLHttpRequest implementation should look something like:

XMLHttpRequest::OnRequestDone(status) {
  if (status != success) {
    ... error handling ...
    return;
  }

  if (isXMLContentType(contentType)) {
    responseXML = parseAsXML(responseText);
  }

  readystate = 4;
  synchronousDispatch("readystatechange");
  synchronousDispatch("load");
  synchronousDispatch("loadend");
}


Another way to look at it is that I think the following code:

xhr = new XMLHttpRequest;
timerId = setInterval(function() { if(xhr.responseXML)
alert(xhr.responseXML); }, 0);
xhr.open(...);
xhr.send();
xhr.onloadend = function() {
  cancelInterval(timerId);
}

should never ever fire the alert.

The whole purpose of firing events asynchronously is to aid
implementations so that they don't need to have a deep callstack when
the event fires, but instead can ensure to be in a stable state when
firing the event. However if the code in question is already started
asynchronously, such as as a result of a network event, then there is
no reason not to fire synchronously.

Firing events asynchronously always introduces hassles. Typically that
conditions change between when the event was scheduled to be fired,
and when the event actually fires. Many times this means that you have
to keep track of the task that will fire the event and under certain
conditions cancel it if what the event indicates is no longer true.
Thus I think we should as a general rule try to fire synchronously
when this doesn't risk destabilizing implementations.

/ Jonas



More information about the whatwg mailing list