W3C home > Mailing lists > Public > public-webapps@w3.org > April to June 2011

Re: What changes to Web Messaging spec are proposed? [Was: Re: Using ArrayBuffer as payload for binary data to/from Web Workers]

From: Kenneth Russell <kbr@google.com>
Date: Fri, 3 Jun 2011 14:54:47 -0700
Message-ID: <BANLkTinaog0JxKN=oT+MnxCJ4Omfmgzu3g@mail.gmail.com>
To: Andrew Wilson <atwilson@google.com>
Cc: Jonas Sicking <jonas@sicking.cc>, Glenn Maynard <glenn@zewt.org>, Dmitry Lomov <dslomov@google.com>, David Levin <levin@chromium.org>, ben turner <bent.mozilla@gmail.com>, "public-webapps@w3.org" <public-webapps@w3.org>, Ian Hickson <ian@hixie.ch>, Travis Leithead <Travis.Leithead@microsoft.com>
On Fri, Jun 3, 2011 at 2:15 PM, Andrew Wilson <atwilson@google.com> wrote:
>
>
> On Fri, Jun 3, 2011 at 1:02 PM, Jonas Sicking <jonas@sicking.cc> wrote:
>>
>> On Fri, Jun 3, 2011 at 11:37 AM, Kenneth Russell <kbr@google.com> wrote:
>> > On Fri, Jun 3, 2011 at 9:46 AM, Glenn Maynard <glenn@zewt.org> wrote:
>> >> On Fri, Jun 3, 2011 at 11:12 AM, Dmitry Lomov <dslomov@google.com>
>> >> wrote:
>> >>> a) Recursive transfer lists. Allow arbitrary objects, not only
>> >>> ArrayBuffers,
>> >>> to appear in transfer lists.  ArrayBuffers that are under objects in
>> >>> transfer lists are transferred, others are cloned.
>> >>
>> >> This again causes the same forwards-compatibility problem.  If you do
>> >> this:
>> >>
>> >> frame = { video: canvasPixelArrayInstance, histogram: arrayBuffer } }
>> >> postMessage({ frame: frame }, { transfer: frame });
>> >>
>> >> and you expect only histogram to be transferred (since that's all that
>> >> supports it when you write this code), your code breaks when
>> >> CanvasPixelArray later supports it.
>> >>
>> >>> b) Transfer lists + separate transferMessage method. We still equip
>> >>> postMessage with transfer lists, these transfer lists list
>> >>> ArrayBuffers, and
>> >>> we provide a separate method transferMessage with recursive transfer
>> >>> semantics.
>> >>> What do people think?
>> >>
>> >> Same problem.
>> >>
>> >> If you want a quicker way to transfer all messages of given types, see
>> >> my previous mail: { transfer: ArrayBuffer }.
>> >
>> > Agreed on these points. Using an object graph for the transfer list
>> > (which is what the recursive transfer list idea boils down to) also
>> > sounds overly complicated.
>> >
>> > May I suggest to reconsider adding another optional array argument to
>> > postMessage for the transfer list, rather than using an object with
>> > special properties?
>> >
>> > Points in favor of adding another optional array argument:
>> >
>> > 1. Less typing, and less possibility that a typo will cause incorrect
>> > behavior:
>> >  worker.postMessage(objectGraph, null, [ arrayBuffer1ToTransfer,
>> > arrayBuffer2ToTransfer ]);
>> >    vs.
>> >  worker.postMessage(objectGraph, { transfer: [
>> > arrayBuffer1ToTransfer, arrayBuffer2ToTransfer] });
>> >
>> > 2. Possibility of using Web IDL to specify the type of the optional
>> > array argument (i.e., "Transferable[]?"). Would be harder to do using
>> > an object -- requiring either specifying another interface type with
>> > the "ports" and "transfer" attributes, or using "any" plus
>> > ECMAScript-specific text.
>> >
>> > Points in favor of using an object:
>> >
>> > 1. Could potentially overload the meaning of the optional ports array
>> > argument, avoiding adding another argument to postMessage.
>> >
>> > 2. More extensible in the future.
>> >
>> > Thoughts?
>>
>> My first thought is that so far no implementer has stepped up and said
>> that changing the meaning of the 'ports' argument would not be
>> acceptable. Would be great if someone who is reading this thread and
>> who works at Google/Apple/Opera could check with the relevant people
>> to see if such a change would be possible.
>
> It's certainly possible - there's nothing intrinsically difficult with
> making this change from an implementor's point of view (I've had my fingers
> in both the WebKit and Chromium MessagePort implementations so I'm
> relatively confident that this would not be prohibitively hard).
> Is it desirable? My knee-jerk reaction is that we should stick with changes
> that are compatible with the existing API (like Ian's original suggestion,
> or adding a separate optional array of transferable objects) - I have no
> data on the number of sites that are using the current API but I don't think
> we should be changing existing APIs with multiple implementations without
> significant motivation. The stated motivations for breaking this API don't
> seem compelling to me given the existence of backwards-compatible
> alternatives.

Drew pointed me off-list to the original discussion motivating the
addition of the optional argument for the array of ports:

http://lists.w3.org/Archives/Public/public-html-comments/2009Mar/0001.html

As I've been thinking more about Ian's original proposal, it seems to
me that I might have misunderstood the intent.

The current optional array of MessagePorts is very close to supporting
the semantic of transfer of ownership that is desired. If a
MessagePort is passed in this array, its ownership is transferred to
the other side. The undesirable aspects seem to be:

1) It doesn't seem to be allowed to refer to those MessagePort objects
in the object graph which is the first argument to postMessage. At
least, it looks to me like the structured clone algorithm will throw a
DATA_CLONE_ERR exception if it encounters a MessagePort object.

2) The array of ports shows up on the other side as the "ports"
property of the MessageEvent.

(1) could be solved, and in a backward-compatible way, by defining the
behavior of MessagePort under structured clone. "Cloning" a
MessagePort would cause a DATA_CLONE_ERR exception to be thrown, but
if structured clone were taught about the objects to be transferred,
then if a MessagePort were transferred, the cloned object graph could
refer to the new instance on the other side.

(2) is somewhat unfortunate but there are at least a few possibilities:
  a) Change the "MessagePort[] ports" property to "Transferable[]
ports", and let all Transferables show up in that array.
  b) Leave the "MessagePort[] ports" property. Filter out all
MessagePorts from the incoming Transferables[], and have only them
show up in the ports array on the other side.
  c) Add a "Transferable[] transfers" property to MessageEvent,
possibly in conjunction with (b).
  d) (c), plus deprecate the ports property of MessageEvent.
  e) ?

(b) gives completely backward compatible behavior and sounds good to
me. I don't see a need to propagate the array of transferables to the
other side, since the object graph will be able to refer to them.

Ian, if this was your intent, I apologize for not understanding it,
but this seems like a way to easily evolve the port array argument to
support transfer of ownership.

-Ken
Received on Friday, 3 June 2011 21:55:12 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:45 GMT