Re: Transferable and structured clones, was: Re: [FileAPI] Deterministic release of Blob proposal

On Tue, Mar 6, 2012 at 12:04 PM, Greg Billock <gbillock@google.com> wrote:
> On Mon, Mar 5, 2012 at 6:46 PM, Charles Pritchard <chuck@jumis.com> wrote:
>> On 3/5/2012 5:56 PM, Glenn Maynard wrote:
>>
>> On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard <chuck@jumis.com> wrote:
>>>
>>> Do you see old behavior working something like the following?
>>>
>>>
>>> var blob = new Blob("my new big blob");
>>> var keepBlob = blob.slice(); destination.postMessage(blob, '*', [blob]);
>>> // is try/catch needed here?
>>
>>
>> You don't need to do that.  If you don't want postMessage to transfer the
>> blob, then simply don't include it in the transfer parameter, and it'll
>> perform a normal structured clone.  postMessage behaves this way in part for
>> backwards-compatibility: so exactly in cases like this, we can make Blob
>> implement Transferable without breaking existing code.
>>
>> See http://dev.w3.org/html5/postmsg/#posting-messages and similar
>> postMessage APIs.
>>
>>
>> Web Intents won't have a transfer map argument.
>> http://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html#widl-Intent-data
>>
>> For the Web Intents structured cloning algorithm, Web Intents would be
>> inserting into step 3:
>>     If input is a Transferable object, add it to the transfer map.
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#internal-structured-cloning-algorithm
>>
>> Then Web Intents would move the first section of the structured cloning
>> algorithm to follow the internal cloning algorithm section, swapping their
>> order.
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data
>>
>> That's my understanding.
>
> We've been discussing the merits of this approach vs using a transfer
> array argument. There's a lot to like about this alternative -- it
> conserves arguments and looks simpler than the transfer map, as well
> as not having the headaches of whether you can do (null, [port]) or
> (port, [port]) and concerns like that.
>
> The advantage of using the transfer map param is that it is more
> contiguous with existing practice. We'd kind of hoped that this
> particular debate was finalized before we got to the point of needing
> to make a decision, so we bluffed and left it out of the web intents
> spec draft. :-) At this point, I'm leaning toward needing to add a
> transfer map parameter, and then dealing with that alongside other
> uses, given the state of thinking on Transferables support and the
> need to make this pretty consistent across structure clone
> invocations.
>
> I do think that complexity might be better solved by the type system
> (i.e. a "new Transferable(ArrayBuffer)"), which would require a
> different developer mechanic to set up clone vs transfer, but would
> relieve complexity in the invocation of structured clone itself:
> transferables could just always transfer transparently. I don't know
> if, given current practice with MessagePort, that kind of solution is
> available.

A change like this would be feasible as long as it doesn't break
compatibility. In other words, the current Transferable array would
still need to be supported, but Transferable instances (or perhaps
instances of some other type) wrapping another Transferable object
would also express the intent.

The current API for Transferable and postMessage was informed by the
realization that the previous sequence<MessagePort> argument to
postMessage was essentially already expressing the Transferable
concept.

I'm not familiar with the Web Intents API, but at first glance it
seems feasible to overload the constructor, postResult and postFailure
methods to support passing a sequence<Transferable> as the last
argument. This would make the API look more like postMessage and avoid
adding more transfer semantics. Is that possible?


>> Something like this may be necessary if Blob were a Transferable:
>> var keepBlob = blob.slice();
>> var intent = new Intent("-x-my-intent", blob);
>> navigator.startActivity(intent, callback);
>>
>>> And we might have an error on postMessage stashing it in the transfer
>>> array if it's not a Transferable on an older browser.
>>
>>
>>
>>
>> Example of how easy the neutered concept applies to Transferrable:
>>
>> var blob = new Blob("my big blob");
>> blob.close();
>>
>>
>> I like the idea of having Blob implement Transferrable and adding close to
>> the Transferrable interface.
>> File.close could have a better relationship with the cache and/or locks on
>> data.

I'm not sure that adding close() to Transferable is a good idea. Not
all Transferable types may want to support that explicit operation.
What about adding close() to Blob, and having the neutering operation
on Blob be defined to call close() on it?

-Ken


>> Some history on Transferrable and structured clones:
>>
>> Note: MessagePort does have a close method and is currently the only
>> Transferrable mentioned in WHATWG:
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#transferable-objects
>>
>> ArrayBuffer is widely implemented. It was the second item to implement
>> Transferrable:
>> http://www.khronos.org/registry/typedarray/specs/latest/#9
>>
>> Subsequently, ImageData adopted Uint8ClampedArray for one of its properties,
>> adopting TypedArrays:
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
>>
>> This has lead to some instability in the structured clone algorithm for
>> ImageData as the typed array object for ImageData is read-only.
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=13800
>>
>> ArrayBuffer is still in a strawman state.
>>
>> -Charles
>>
>>
>

Received on Tuesday, 6 March 2012 21:18:41 UTC