[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [hybi] Races in websocket API?



On Fri, Nov 20, 2009 at 7:16 AM, Jamie Lokier <jamie at shareable.org> 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.
>

Is that behavior considered a bug in the debugger or a design
constraint for JavaScript APIs in general?

> Second, all recent browsers have multi-threaded Javascript, under
> either Google's WorkerPool API, or WHATWG's Web Workers.
>

How could WorkerPool or Web Workers be used to preemptively schedule
notification of the "open" event after the first line executes but
before the second line executes in the same JavaScript execution
context?

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

> 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?
>

My understanding is that although Web Workers provide multiple threads
of execution for JavaScript, they work with independent state and
communicate via serialized messages.  So, from the perspective of each
Web Worker, the execution model is still single-threaded.

If this was not the case, then locking primitives would be necessary
in JavaScript to support multiple threads of execution accessing the
same shared state.

I believe the correct mental model for this is the following:

[single-threaded perspective]
  var ws = new WebSocket("ws://kaazing.net/echo");
  ws.onopen = function() { console.log("OPEN"); }
  [yield control to deliver pending events such as "open"]

> 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.
>

This was the proposal we made for TCPConnection at the time, because
it mirrored the disconnect() call.  Given the current WebSocket API,
the natural equivalent today would probably be open() rather than
connect().

Kind Regards,
John Fallows
-- 
>|< Kaazing Corporation >|<
John Fallows | CTO | +1.650.960.8148
888 Villa St, Ste 410 | Mountain View, CA 94041, USA

Note Well: Messages sent to this mailing list are the opinions of the senders and do not imply endorsement by the IETF.