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

On Mon, Jun 20, 2011 at 3:54 PM, Ian Hickson <ian@hixie.ch> wrote:
>
> So the proposal that seems to address the most concerns raised in this
> thread would be to have postMessage() work like this:
>
>   postMessage({ object }, [ array ]);
>
> ...with it resulting in an event that contains both {object} and [array],
> where everything in the array is transferred, and everything in the object
> is by default cloned unless it's in both the {object} and the [array] in
> which case the transferred copy is used instead.
>
> That way you can keep doing the simple thing to send a port:
>
>   postMessage('vend-reply', [port]);
>
> ...and you can pass array buffers in complex data structures as copies:
>
>   postMessage({ data: arrayBuffer });
>
> ...and you can send them as clones without losing the structure, though
> you have to walk your structure to list all the objects you care about:
>
>   postMessage({ data: arrayBuffer }, [arrayBuffer]);
>
> ...but you don't _have_ to do something like this to send a port:
>
>   postMessage(['vend-reply', port], [port]);
>
> ...which seems a bit ugly.
>
> It also means you can both transfer and copy, if that's what you want:
>
>   postMessage([thisArrayBufferIsCopied, thisPortIsTransferred],
>               [thisPortIsTransferred]);
>
> This also has the benefit of being backwards-compatible, at least if I
> keep an attribute on the event on the other side called "ports" that
> includes the transferred objects (maybe another attribute should be
> included that also returns the same array, since 'ports' would now be a
> confusing misnomer). Alternatively, we can rename 'ports' to something
> else and just have WebKit support 'ports' for legacy reasons. If we do
> this I can also change the 'connect' event to make more sense.
>
> Opinions?

I still think that that transferring both the data field and the
"array formerly known as ports array" is a bad idea. It creates a
strange duality in where data can appear on the receiving side which
complicates the protocol definitions that people have to define.

I agree that

postMessage(['vend-reply', port], [port]);

is a big ugly, but it still seems better to me since it creates a
simpler and more consistent API on the receiver side.

If data appears both in the .ports array and the .data property, then
people will be tempted to create protocols which only work if the
array buffer is transferred, i.e. if the receiver only looks in
.ports. I.e. people will likely end up with equally ugly solutions
like:

postMessage('vend-reply', [createClone(arraybuffer)]);

(which also suffers from being worse performance than simply having
postMessage copy the buffer).

/ Jonas

Received on Tuesday, 21 June 2011 06:44:04 UTC