W3C home > Mailing lists > Public > whatwg@whatwg.org > November 2009

[whatwg] [hybi] Races in websocket API?

From: Maciej Stachowiak <mjs@apple.com>
Date: Sun, 22 Nov 2009 19:50:46 -0800
Message-ID: <CC64D0CA-043C-4B38-ADF8-69219D308BF8@apple.com>

On Nov 20, 2009, at 7:16 AM, Jamie Lokier wrote:

> John Fallows wrote:
>> Greg,
>>
>> We raised this as a potential issue during the API design for
>> WebSocket (back when it was called TCPConnection), indicating that a
>> separate method might be desirable that could be called after the
>> WebSocket was constructed and event handlers attached.
>>
>> But the decision was made that a single-threaded execution  
>> environment
>> made a separate method unnecessary, because the execution of the
>> onopen handler (for example) could not preempt the execution of the
>> following 2 lines of JavaScript code:
>>
>> var ws = new WebSocket("ws://kaazing.net/echo");
>> ws.onopen = function() { console.log("OPEN"); }
>>
>> Therefore, by the time the open event is delivered, the onopen  
>> handler
>> would have already been attached.
>
> Unfortunately the single-threaded assumption is not correct.
>
> First, it's already been mentioned that when running Javascript under
> a debugger under at least one browser, events can be sent and lost
> before the second line executes.
>
> Second, all recent browsers have multi-threaded Javascript, under
> either Google's WorkerPool API, or WHATWG's Web Workers.
>
> Web Workers have been suggested as a way to use WebSocket effectively,
> but this single-threaded assumption might make that combination
> difficult to use.  What happens when you create a new WebSocket object
> in a Web Worker?  Can that be done safely?

Short version: yes, WebSocket can work fine in a Web Worker.

Slightly longer version: "Single-threaded" is perhaps a misleading way  
to characterize the required condition. Here's a slightly more precise  
description: all WebSocket events are delivered on the logical  
"thread" of JavaScript execution that spawned them (either a UI thread  
or a Worker or what have you). The event delivery is not re-entrant -  
the event will only be sent the next time that thread of execution  
drops back into the event loop. And you can't pass a WebSocket from  
one thread to another. This means that any time you do a sequence like  
this:

   var ws = new WebSocket("ws://kaazing.net/echo");
   ws.onopen = function() { console.log("OPEN"); }

You can be guaranteed that no "open" event will fire before the  
"onopen" attribute is set - the WebSocket object cannot deliver events  
until the event loop on the thread that created it is free.

  -  Maciej

>
> I'm surprised at that, given WHATWG is involved with both WebSocket
> and Web Workers.
>
> An obvious solution is a connect() method, similar to XmlHttpRequest's
> send() method.
>
> -- Jamie
> _______________________________________________
> hybi mailing list
> hybi at ietf.org
> https://www.ietf.org/mailman/listinfo/hybi
Received on Sunday, 22 November 2009 19:50:46 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 16:59:19 UTC