This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 12947 - Extend postMessage to support general transfer-of-ownership semantics
Summary: Extend postMessage to support general transfer-of-ownership semantics
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: Web Messaging (editor: Ian Hickson) (show other bugs)
Version: unspecified
Hardware: All All
: P1 blocker
Target Milestone: ---
Assignee: Ian 'Hixie' Hickson
QA Contact: public-webapps-bugzilla
URL: http://lists.w3.org/Archives/Public/p...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-13 18:14 UTC by Travis Leithead [MSFT]
Modified: 2011-06-23 23:52 UTC (History)
11 users (show)

See Also:


Attachments

Description Travis Leithead [MSFT] 2011-06-13 18:14:44 UTC
This is a summary of the full discussion here: http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0304.html

This bug proposes some modifications to the postMessage API to allow it to support generic "transfer-of-ownership" semantics for ArrayBuffer (TypedArray specification) and other transferrable objects in the future, in a backwards-compatible way with existing implementations of postMessage.

The changes are as follows:
1. The 2nd parameter to postMessage shall be generalized to be an array of "Transferrable" types, of which MessagePort will become the first derived type.
2. The spec should define generally what the cloning process of Transferrable objects is, but might leave the specifics up to the specs that derive objects from this generic type. In general, objects located in the Transferrable[] array will be references to object instances in the data payload (param 1), and act as an opt-in flag for transfer-of-ownership behavior. If a transferrable object is found in the data payload, but it is not in the list of transferrable objects, then that object will be cloned as defined in the structured clone algorithm of the HTML5 spec. Otherwise, that object instance will have its ownership transferred.

Transfer-of-ownership is the generic term for the process currently applied to MessagePort objects when passed in the 2nd parameter. The object is "closed" on the sending side, and "activated" on the recieving side. Attempts to use the object on the sending side (after sending) will "not work" (to be defined per-object type).

It is also recommended that the HTML5 "structured clone algorithm" be updated to include ArrayBuffer objects (or made extensible so that the TypedArray specification and "plug-in" their ArrayBuffer objects into the algorithm).
Comment 1 Jonas Sicking (Not reading bugmail) 2011-06-13 18:51:15 UTC
Also, the MessageEvent.data attribute is set to the newly created MessagePort when the "connect" event is fired on the global object of a newly connected to shared worker.

After all this is done, the MessageEvent.ports attribute is redundant. It would be nice if it was marked deprecated or otherwise removed from the spec. This wouldn't put any requirements on that existing implementations immediately remove the attribute, but rather they can do so at their own pace as to keep backwards compatibility.


All of this has the following advantages to the existing API or other proposals:

1. MessagePorts can participate in the main cloned object graph. This allows
   them to exist along with whatever meta-data is transferred with the port.
2. A single mechanism is used for all transferable objects, MessagePorts and
   ArrayBuffers alike.
3. All objects which are mutated by the structured clone are explicitly
   enumerated, making it much less likely that surprising mutations will
   happen. This is important for for example the case when code receives data
   from other subsystems which are to be transferred.
4. It's possible to transfer some ArrayBuffers while cloning others. This can
   be good for performance as well as simplicity of code. Transferring
   ownership of a buffer comes with some overhead, so isn't a good idea to do
   if there are lots of small buffers in the sent data. Also, if you want to
   keep a copy of the sent data for further processing, not transferring it
   means that you don't have to explicitly create a copy before calling
   postMessage.
Comment 2 Travis Leithead [MSFT] 2011-06-13 19:53:47 UTC
In my original mail, I considered describing the behavior of MessagePorts in the data payload (your #1 advantage above), but I immediately saw a problem with that--if you pass a MessagePort in the data payload, but don't list it in the transferrable array, then the API has to throw (since there's not clone behavior for message ports that doesn't transfer ownership). This is a unique behavior for message ports that wouldn't apply to any other transferrable types, so I figured it might not be worth adding this extra complexity (by allowing #1).
Comment 3 Jonas Sicking (Not reading bugmail) 2011-06-13 20:06:08 UTC
Forgetting to put a MessagePort in the transferrable array would be pretty quickly discovered by the developer as an exception is thrown.

Additionally, by forcing the MessagePort to participate in the data object graph, it makes the API more consistent in that *everything* that is to be sent to the worker must appear in the object graph on the sender side, and will appear in the object graph in the receiver side. I always thought that the current "all data goes in the first argument, except message ports which go in the second".

Additionally, forcing MessagePorts to appear in the object graph is what allows us to remove the .ports property.

So while I agree that allowing MessagePorts to appear in the data object graph does introduce one type of complexity, it IMHO reduces complexity much more in other areas.
Comment 4 Ian 'Hixie' Hickson 2011-06-13 22:07:02 UTC
The proposals here make sense, but it seems really lame to have to write:

   api.postMessage(['get-contacts', port], [port]);

...instead of:

   api.postMessage('get-contacts', port);

...as we can do today.
Comment 5 Jonas Sicking (Not reading bugmail) 2011-06-14 00:16:49 UTC
Indeed. For the case of simply sending over a port you end up with more syntax.

However I would argue that the advantages listed in comment 1 as well as

5. Consistency in where data shows up on the receiver side (always shows up in
   the event.data member).
6. Consistency in where to send data on the sender side.

still means that the advantages outweigh the disadvantages. IMHO.
Comment 6 Glenn Maynard 2011-06-14 04:39:09 UTC
(In reply to comment #4)
>    api.postMessage(['get-contacts', port], [port]);

It's no more work than the ArrayBuffer equivalent, and I think the benefits of having ports alongside related data far outweighs it.  But, if object constructors are allowed in the list, then developers can write a trivial helper:

api.prototype.postMessageWithPorts = function(obj) { this.postMessage(obj, [MessagePort]); }

api.postMessageWithPorts(['get-contacts', port]);

which still provides an explicit declaration that you expect postMessage to be mutating for specific types of objects in the graph, but giving the API sugar to keep high-level code pretty.
Comment 7 Jonas Sicking (Not reading bugmail) 2011-06-14 08:01:41 UTC
I'm really not a fan of letting you say "transfer all objects of type X". It's a big foot-gun. I'd much rather that we wait with adding such syntax sugar until developers are really asking for it after having tested with the safer API.
Comment 8 Jonas Sicking (Not reading bugmail) 2011-06-14 08:02:49 UTC
Or better yet. Wait until people start writing helper functions which traverse the graph and find all objects of a given type and add them to the "transfers" array.
Comment 9 Glenn Maynard 2011-06-15 05:33:07 UTC
(In reply to comment #7)
> I'm really not a fan of letting you say "transfer all objects of type X". It's
> a big foot-gun.

I think I disagree, but it can definitely wait.
Comment 10 Ian 'Hixie' Hickson 2011-06-21 23:46:50 UTC
Proposal:
http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/1184.html
Comment 11 Travis Leithead [MSFT] 2011-06-22 03:44:03 UTC
You know you've reached a good decision whem most folks are relatively unhappy with the decision, but are willing to live with it given the constraints.

I'm satisfied with the proposal as noted in the link.
Comment 12 contributor 2011-06-23 23:49:09 UTC
Checked in as WHATWG revision r6273.
Check-in comment: add infrastructure to postMessage() to support ArrayBuffer cloning
http://html5.org/tools/web-apps-tracker?from=6272&to=6273