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

On Fri, Jun 3, 2011 at 2:54 PM, Kenneth Russell <kbr@google.com> wrote:
> 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) ?

e) Keep "MessagePort[] ports" the way it is but deprecate it.

I like that option the best. This, together with Kenneth's (1)
proposal above, also gives a better API for transferring message ports
as they don't have to be sent in a separate property, but can appear
in the normal object graph.

/ Jonas

Received on Friday, 3 June 2011 22:03:50 UTC