Re: [FileAPI] Deterministic release of Blob proposal

On Tue, Mar 6, 2012 at 5:12 PM, Feras Moussa <ferasm@microsoft.com> wrote:
>> From: Arun Ranganathan [mailto:aranganathan@mozilla.com]
>> Sent: Tuesday, March 06, 2012 1:27 PM
>> To: Feras Moussa
>> Cc: Adrian Bateman; public-webapps@w3.org; Ian Hickson; Anne van Kesteren
>> Subject: Re: [FileAPI] Deterministic release of Blob proposal
>>
>> Feras,
>>
>> In practice, I think this is important enough and manageable enough to include in the spec., and I'm willing to slow the train down if necessary, but I'd like to understand a few things first.  Below:
>> ________________________________________
>> > At TPAC we discussed the ability to deterministically close blobs with a few
>> > others.
>  > >
>> > As we’ve discussed in the createObjectURL thread[1], a Blob may represent
>> > an expensive resource (eg. expensive in terms of memory, battery, or disk
>> > space). At present there is no way for an application to deterministically
>> > release the resource backing the Blob. Instead, an application must rely on
>> > the resource being cleaned up through a non-deterministic garbage collector
>> > once all references have been released. We have found that not having a way
>> > to deterministically release the resource causes a performance impact for a
>> > certain class of applications, and is especially important for mobile applications
>> > or devices with more limited resources.
>> >
>> > In particular, we’ve seen this become a problem for media intensive applications
>> > which interact with a large number of expensive blobs. For example, a gallery
>> > application may want to cycle through displaying many large images downloaded
>> > through websockets, and without a deterministic way to immediately release
>> > the reference to each image Blob, can easily begin to consume vast amounts of
>> > resources before the garbage collector is executed.
>  > >
>> > To address this issue, we propose that a close method be added to the Blob
>> > interface.
>> > When called, the close method should release the underlying resource of the
>> > Blob, and future operations on the Blob will return a new error, a ClosedError.
>> > This allows an application to signal when it's finished using the Blob.
>> >
>
>> Do you agree that Transferable
>> (http://dev.w3.org/html5/spec/Overview.html#transferable-objects) seems to be what
>> we're looking for, and that Blob should implement Transferable?
>>
>> Transferable addresses the use case of copying across threads, and "neuters" the source
>> object (though honestly, the word "neuter" makes me wince -- naming is a problem on the
>> web).  We can have a more generic method on Transferable that serves our purpose here,
>> rather than *.close(), and Blob can avail of that.  This is something we can work out with HTML,
>> and might be the right thing to do for the platform (although this creates something to think
>> about for MessagePort and for ArrayBuffer, which also implement Transferable).
>>
>> I agree with your changes, but am confused by some edge cases:
>>> To support this change, the following changes in the File API spec are needed:
>> >
>>> * In section 6 (The Blob Interface)
>>>  - Addition of a close method. When called, the close method releases the
>>> underlying resource of the Blob. Close renders the blob invalid, and further
>>> operations such as URL.createObjectURL or the FileReader read methods on
>>> the closed blob will fail and return a ClosedError.  If there are any non-revoked
>>> URLs to the Blob, these URLs will continue to resolve until they have been
>>> revoked.
>>>  - For the slice method, state that the returned Blob is a new Blob with its own
>>> lifetime semantics – calling close on the new Blob is independent of calling close
>>> on the original Blob.
>>>
>>> *In section 8 (The FIleReader Interface)
>>> - State the FileReader reads directly over the given Blob, and not a copy with
>>> an independent lifetime.
>>>
>>> * In section 10 (Errors and Exceptions)
>>> - Addition of a ClosedError. If the File or Blob has had the close method called,
>>> then for asynchronous read methods the error attribute MUST return a
>>> “ClosedError” DOMError and synchronous read methods MUST throw a
>>> ClosedError exception.
>>>
>>> * In section 11.8 (Creating and Revoking a Blob URI)
>>> - For createObjectURL – If this method is called with a closed Blob argument,
>>> then user agents must throw a ClosedError exception.
>>>
>>> Similarly to how slice() clones the initial Blob to return one with its own
>>> independent lifetime, the same notion will be needed in other APIs which
>>> conceptually clone the data – namely FormData, any place the Structured Clone
>>> Algorithm is used, and BlobBuilder.
>>> Similarly to how FileReader must act directly on the Blob’s data, the same notion
>>> will be needed in other APIs which must act on the data - namely XHR.send and
>>> WebSocket. These APIs will need to throw an error if called on a Blob that was
>>> closed and the resources are released.
>>>
>> So Blob.slice() already presumes a new Blob, but I can certainly make this clearer.
>> And I agree with the changes above, including the addition of something liked
>> ClosedError (though I suppose this is an important enough error + exception to hash
>> out with HTML and DOM4, and once again, the name is TBD).
>>
>> In your implementation, what happens exactly to Eric's edge cases, namely:
>>
>> xhr.send(blob);
>> blob.close(); // method name TBD
> In our implementation, this case would fail. We think this is reasonable because the
> need for having a close() method is to allow deterministic release of the resource.
> Having to wait for send to complete before releasing is non-deterministic, and would go
> against the goal of close().

Why would this be different than postMessage in that respect?  In
either case, you're telling the system that you're done with it, and
that it can go away as soon as the other holder of the blob [or the
holder of the other copy, if you want to see it that way] drops it.
If you post it to a worker and drop it locally, the disk resource
doesn't go away until the worker's done with it.  If you XHR.send it
and drop it locally, the disk resource doesn't go away until the XHR
is done sending it.

>>
>> // AND
>>
>> frameRef.src = URL.createObjectURL(blob);
>> blob.close() // method name TBD
>>
>> In my opinion, the first (using xhr) should succeed.  In the second, frameRef.src works,
>> but subsequent attempts to mint a Blob URI for the same 'blob' resource fail.  Does this
>> hold true for you?
> We agree that subsequent attempts to mint a blob URI for a blob that has been closed
> should fail, and is what I tried to clarify in my comments in 'section 6'.
> As an aside, the above example shows navigation to a Blob URI - this is not something we
> Currently support or intend to support.

OK, try again as Charles suggested with an image tag instead.

Also, what about msSaveBlob--same as XHR, or same as postMessage?

>>
>> -- A*

Received on Wednesday, 7 March 2012 23:11:12 UTC