Re: [FileAPI] Deterministic release of Blob proposal

2012-03-08 Thread Anne van Kesteren
On Thu, 08 Mar 2012 00:58:02 +0100, Feras Moussa fer...@microsoft.com  
wrote:

In the case where close was called on a Blob that is being used in a
pending request, then the request should be canceled. The expected
result is the same as if abort() was called.


It seems very weird that invoking close() on Blob would invoke abort() on  
XMLHttpRequest. Would it not be better to not set the close flag until it  
is no longer in use?



--
Anne van Kesteren
http://annevankesteren.nl/



Re: [FileAPI] Deterministic release of Blob proposal

2012-03-08 Thread Glenn Maynard
On Wed, Mar 7, 2012 at 5:58 PM, Feras Moussa fer...@microsoft.com wrote:

 In the case where close was called on a Blob that is being used in a
 pending request, then the request should be canceled. The expected
 result is the same as if abort() was called.


This would complicate every API that uses Blobs.  APIs should just make a
copy of the underlying data.  It minimizes the effects on other APIs and
makes the behavior consistently understandable.  In the case of XHR2, the
only change you'd need to make to that API, I think, would be for send() to
say if *data* is a *neutered* object, throw an exception in step 3 of
send().  The rest is already dealt with, since XHR2 already makes a copy
(Let the request entity body be the raw data represented by data.).

It simply means that any time you pass a Blob to a native API, the Blob is
implicitly sliced to create an independent (shallow, of course) copy before
it's used or stashed for later use.

That way, APIs never have to deal with blobs being released out from
underneath them, which could complicate things significantly (eg. you might
be accessing the blob's data from an asynchronous section).

 var a = new Image();
  a.onerror = function() { console.log(Oh no, my parent was neutered!);
 }; a.src = URL.createObjectURL(blob); blob.close();
 
  Is that error going to hit?
 I documented this in my proposal, but in this case the URI would have
 been minted prior to calling close. The Blob URI would still resolve
 until it has been revoked, so in your example onerror would not be hit
 due to calling close.


I do think this is what should happen, because createObjectURL would create
a copy of blob.  It seems a bit inconsistent with what your proposal,
though (if blob.close() always releases the underlying data, to the point
of aborting asynchronous XHR, then it should do so if it has associated
URLs, too).

-- 
Glenn Maynard


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-07 Thread Anne van Kesteren
On Wed, 07 Mar 2012 02:12:39 +0100, Feras Moussa fer...@microsoft.com  
wrote:

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.


Reasonable or not, would fail is not something we can put in a standard.  
What happens exactly? What if a connection is established and data is  
being transmitted already?



--
Anne van Kesteren
http://annevankesteren.nl/



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

2012-03-07 Thread Kenneth Russell
On Tue, Mar 6, 2012 at 6:29 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Mar 6, 2012 at 4:24 PM, Michael Nordman micha...@google.com wrote:

  You can always call close() yourself, but Blob.close() should use the
  neuter mechanism already there, not make up a new one.

 Blobs aren't transferable, there is no existing mechanism that applies
 to them. Adding a blob.close() method is independent of making blob's
 transferable, the former is not prerequisite on the latter.


 There is an existing mechanism for closing objects.  It's called
 neutering.  Blob.close should use the same terminology, whether or not the
 object is a Transferable.

 On Tue, Mar 6, 2012 at 4:25 PM, Kenneth Russell k...@google.com wrote:

 I would be hesitant to impose a close() method on all future
 Transferable types.


 Why?  All Transferable types must define how to neuter objects; all close()
 does is trigger it.

 I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.


 That's often not possible, when the ArrayBuffer is returned to you from an
 API (eg. XHR2).

 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.


 No new semantics need to be defined; the semantics of Transferable are
 defined by postMessage and are the same for all transferable objects.
 That's already done.  The only thing that needs to be defined is how to
 neuter an object, which is what Blob.close() has to define anyway.

 Using Transferable for Blob will allow Blobs, ArrayBuffers, and any future
 large, structured clonable objects to all be released with the same
 mechanisms: either pass them in the transfer argument to a postMessage
 call, or use the consistent, identical close() method inherited from
 Transferable.  This allows developers to think of the transfer list as a
 list of objects which won't be needed after the postMessage call.  It
 doesn't matter that the underlying optimizations are different; the visible
 side-effects are identical (the object can no longer be accessed).

Closing an object, and neutering it because it was transferred to a
different owner, are different concepts. It's already been
demonstrated that Blobs, being read-only, do not need to be
transferred in order to send them efficiently from one owner to
another. It's also been demonstrated that Blobs can be resource
intensive and that an explicit closing mechanism is needed.

I believe that we should fix the immediate problem and add a close()
method to Blob. I'm not in favor of adding a similar method to
ArrayBuffer at this time and therefore not to Transferable. There is a
high-level goal to keep the typed array specification as minimal as
possible, and having Transferable support leak in to the public
methods of the interfaces contradicts that goal.

-Ken



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

2012-03-07 Thread Eric U
On Wed, Mar 7, 2012 at 11:38 AM, Kenneth Russell k...@google.com wrote:
 On Tue, Mar 6, 2012 at 6:29 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Mar 6, 2012 at 4:24 PM, Michael Nordman micha...@google.com wrote:

  You can always call close() yourself, but Blob.close() should use the
  neuter mechanism already there, not make up a new one.

 Blobs aren't transferable, there is no existing mechanism that applies
 to them. Adding a blob.close() method is independent of making blob's
 transferable, the former is not prerequisite on the latter.


 There is an existing mechanism for closing objects.  It's called
 neutering.  Blob.close should use the same terminology, whether or not the
 object is a Transferable.

 On Tue, Mar 6, 2012 at 4:25 PM, Kenneth Russell k...@google.com wrote:

 I would be hesitant to impose a close() method on all future
 Transferable types.


 Why?  All Transferable types must define how to neuter objects; all close()
 does is trigger it.

 I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.


 That's often not possible, when the ArrayBuffer is returned to you from an
 API (eg. XHR2).

 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.


 No new semantics need to be defined; the semantics of Transferable are
 defined by postMessage and are the same for all transferable objects.
 That's already done.  The only thing that needs to be defined is how to
 neuter an object, which is what Blob.close() has to define anyway.

 Using Transferable for Blob will allow Blobs, ArrayBuffers, and any future
 large, structured clonable objects to all be released with the same
 mechanisms: either pass them in the transfer argument to a postMessage
 call, or use the consistent, identical close() method inherited from
 Transferable.  This allows developers to think of the transfer list as a
 list of objects which won't be needed after the postMessage call.  It
 doesn't matter that the underlying optimizations are different; the visible
 side-effects are identical (the object can no longer be accessed).

 Closing an object, and neutering it because it was transferred to a
 different owner, are different concepts. It's already been
 demonstrated that Blobs, being read-only, do not need to be
 transferred in order to send them efficiently from one owner to
 another. It's also been demonstrated that Blobs can be resource
 intensive and that an explicit closing mechanism is needed.

 I believe that we should fix the immediate problem and add a close()
 method to Blob. I'm not in favor of adding a similar method to
 ArrayBuffer at this time and therefore not to Transferable. There is a
 high-level goal to keep the typed array specification as minimal as
 possible, and having Transferable support leak in to the public
 methods of the interfaces contradicts that goal.

This makes sense to me.  Blob needs close independent of whether it's
in Transferable, and Blob has no need to be Transferable, so let's not
mix the two.



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

2012-03-07 Thread Charles Pritchard

On Mar 7, 2012, at 11:38 AM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 6, 2012 at 6:29 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Mar 6, 2012 at 4:24 PM, Michael Nordman micha...@google.com wrote:
 
 You can always call close() yourself, but Blob.close() should use the
 neuter mechanism already there, not make up a new one.
 
 Blobs aren't transferable, there is no existing mechanism that applies
 to them. Adding a blob.close() method is independent of making blob's
 transferable, the former is not prerequisite on the latter.
 
 
 There is an existing mechanism for closing objects.  It's called
 neutering.  Blob.close should use the same terminology, whether or not the
 object is a Transferable.
 
 On Tue, Mar 6, 2012 at 4:25 PM, Kenneth Russell k...@google.com wrote:
 
 I would be hesitant to impose a close() method on all future
 Transferable types.
 
 
 Why?  All Transferable types must define how to neuter objects; all close()
 does is trigger it.
 
 I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.
 
 
 That's often not possible, when the ArrayBuffer is returned to you from an
 API (eg. XHR2).
 
 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.
 
 
 No new semantics need to be defined; the semantics of Transferable are
 defined by postMessage and are the same for all transferable objects.
 That's already done.  The only thing that needs to be defined is how to
 neuter an object, which is what Blob.close() has to define anyway.
 
 Using Transferable for Blob will allow Blobs, ArrayBuffers, and any future
 large, structured clonable objects to all be released with the same
 mechanisms: either pass them in the transfer argument to a postMessage
 call, or use the consistent, identical close() method inherited from
 Transferable.  This allows developers to think of the transfer list as a
 list of objects which won't be needed after the postMessage call.  It
 doesn't matter that the underlying optimizations are different; the visible
 side-effects are identical (the object can no longer be accessed).
 
 Closing an object, and neutering it because it was transferred to a
 different owner, are different concepts. It's already been
 demonstrated that Blobs, being read-only, do not need to be
 transferred in order to send them efficiently from one owner to
 another. It's also been demonstrated that Blobs can be resource
 intensive and that an explicit closing mechanism is needed.
 
 I believe that we should fix the immediate problem and add a close()
 method to Blob. I'm not in favor of adding a similar method to
 ArrayBuffer at this time and therefore not to Transferable. There is a
 high-level goal to keep the typed array specification as minimal as
 possible, and having Transferable support leak in to the public
 methods of the interfaces contradicts that goal.

I think there's broad enough consensus amongst vendors to table the discussion 
about adding close to Transferable.

Would you please let me know why ypu believe ArrayBuffer should not have a 
close method?

I would like some clarity here. The Typed Array spec would not be cluttered by 
the addition of a simple close method.

I work much more with ArrayBuffer than Blob. I suspect others will too as they 
progress with more advanced and resource intensive applications.

What is the use-case distinction between close of immutable blob and close of a 
mutable buffer?

-Charles


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

2012-03-07 Thread Greg Billock
On Tue, Mar 6, 2012 at 1:18 PM, Kenneth Russell k...@google.com wrote:
 On Tue, Mar 6, 2012 at 12:04 PM, Greg Billock gbill...@google.com wrote:
 On Mon, Mar 5, 2012 at 6:46 PM, Charles Pritchard ch...@jumis.com wrote:
 On 3/5/2012 5:56 PM, Glenn Maynard wrote:

 On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@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 sequenceMessagePort 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 sequenceTransferable as the last
 argument. This would make the API look more like postMessage and avoid
 adding more transfer semantics. Is that possible?

Yes. That's our current plan.

-Greg



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

2012-03-07 Thread Kenneth Russell
On Wed, Mar 7, 2012 at 12:02 PM, Charles Pritchard ch...@jumis.com wrote:

 On Mar 7, 2012, at 11:38 AM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 6, 2012 at 6:29 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Mar 6, 2012 at 4:24 PM, Michael Nordman micha...@google.com wrote:

 You can always call close() yourself, but Blob.close() should use the
 neuter mechanism already there, not make up a new one.

 Blobs aren't transferable, there is no existing mechanism that applies
 to them. Adding a blob.close() method is independent of making blob's
 transferable, the former is not prerequisite on the latter.


 There is an existing mechanism for closing objects.  It's called
 neutering.  Blob.close should use the same terminology, whether or not the
 object is a Transferable.

 On Tue, Mar 6, 2012 at 4:25 PM, Kenneth Russell k...@google.com wrote:

 I would be hesitant to impose a close() method on all future
 Transferable types.


 Why?  All Transferable types must define how to neuter objects; all close()
 does is trigger it.

 I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.


 That's often not possible, when the ArrayBuffer is returned to you from an
 API (eg. XHR2).

 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.


 No new semantics need to be defined; the semantics of Transferable are
 defined by postMessage and are the same for all transferable objects.
 That's already done.  The only thing that needs to be defined is how to
 neuter an object, which is what Blob.close() has to define anyway.

 Using Transferable for Blob will allow Blobs, ArrayBuffers, and any future
 large, structured clonable objects to all be released with the same
 mechanisms: either pass them in the transfer argument to a postMessage
 call, or use the consistent, identical close() method inherited from
 Transferable.  This allows developers to think of the transfer list as a
 list of objects which won't be needed after the postMessage call.  It
 doesn't matter that the underlying optimizations are different; the visible
 side-effects are identical (the object can no longer be accessed).

 Closing an object, and neutering it because it was transferred to a
 different owner, are different concepts. It's already been
 demonstrated that Blobs, being read-only, do not need to be
 transferred in order to send them efficiently from one owner to
 another. It's also been demonstrated that Blobs can be resource
 intensive and that an explicit closing mechanism is needed.

 I believe that we should fix the immediate problem and add a close()
 method to Blob. I'm not in favor of adding a similar method to
 ArrayBuffer at this time and therefore not to Transferable. There is a
 high-level goal to keep the typed array specification as minimal as
 possible, and having Transferable support leak in to the public
 methods of the interfaces contradicts that goal.

 I think there's broad enough consensus amongst vendors to table the 
 discussion about adding close to Transferable.

 Would you please let me know why ypu believe ArrayBuffer should not have a 
 close method?

 I would like some clarity here. The Typed Array spec would not be cluttered 
 by the addition of a simple close method.

It's certainly a matter of opinion -- but while it's only the addition
of one method, it changes typed arrays' semantics to be much closer to
manual memory allocation than they currently are. It would be a
further divergence in behavior from ordinary ECMAScript arrays.

The TC39 working group, I have heard, is incorporating typed arrays
into the language specification, and for this reason I believe extreme
care is warranted when adding more functionality to the typed array
spec. The spec can certainly move forward, but personally I'd like to
check with TC39 on semantic changes like this one. That's the
rationale behind my statement above about preferring not to add this
method at this time.

-Ken


 I work much more with ArrayBuffer than Blob. I suspect others will too as 
 they progress with more advanced and resource intensive applications.

 What is the use-case distinction between close of immutable blob and close of 
 a mutable buffer?

 -Charles



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

2012-03-07 Thread Charles Pritchard

On 3/7/12 12:34 PM, Kenneth Russell wrote:

On Wed, Mar 7, 2012 at 12:02 PM, Charles Pritchardch...@jumis.com  wrote:

On Mar 7, 2012, at 11:38 AM, Kenneth Russellk...@google.com  wrote:


I believe that we should fix the immediate problem and add a close()
method to Blob. I'm not in favor of adding a similar method to
ArrayBuffer at this time and therefore not to Transferable. There is a
high-level goal to keep the typed array specification as minimal as
possible, and having Transferable support leak in to the public
methods of the interfaces contradicts that goal.

I think there's broad enough consensus amongst vendors to table the discussion 
about adding close to Transferable.

Would you please let me know why ypu believe ArrayBuffer should not have a 
close method?

I would like some clarity here. The Typed Array spec would not be cluttered by 
the addition of a simple close method.

It's certainly a matter of opinion -- but while it's only the addition
of one method, it changes typed arrays' semantics to be much closer to
manual memory allocation than they currently are. It would be a
further divergence in behavior from ordinary ECMAScript arrays.

The TC39 working group, I have heard, is incorporating typed arrays
into the language specification, and for this reason I believe extreme
care is warranted when adding more functionality to the typed array
spec. The spec can certainly move forward, but personally I'd like to
check with TC39 on semantic changes like this one. That's the
rationale behind my statement above about preferring not to add this
method at this time.


Searching through the net tells me that this has been a rumor for years.

I agree with taking extreme care -- so let's isolate one more bit of 
information:


Is ArrayBuffer being proposed for TC39 incorporation, or is it only the 
Typed Arrays? The idea here is to alter ArrayBuffer, an object which can 
be neutered via transfer map. It seems a waste to have to create a 
Worker to close down buffer views.


Will TC39 have anything to say about the neuter concept and/or Web 
Messaging?



Again, I'm bringing this up for the same practical experience that 
Blob.close() was brought up. I do appreciate that read/write allocation 
is a separate semantic from write-once/read-many allocation.


I certainly don't want to derail the introduction of Typed Array into 
TC39. I don't want to sit back for two years either, while the 
ArrayBuffer object is in limbo.


If necessary, I'll do some of the nasty test work of creating a worker 
simply to destroy buffers, and report back on it.

var worker = new Worker('trash.js');
worker.postMessage(null,[bufferToClose]);
worker.close();
vs.
bufferToClose.close();



-Charles



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

2012-03-07 Thread Kenneth Russell
On Wed, Mar 7, 2012 at 1:00 PM, Charles Pritchard ch...@jumis.com wrote:
 On 3/7/12 12:34 PM, Kenneth Russell wrote:

 On Wed, Mar 7, 2012 at 12:02 PM, Charles Pritchardch...@jumis.com
  wrote:

 On Mar 7, 2012, at 11:38 AM, Kenneth Russellk...@google.com  wrote:

 I believe that we should fix the immediate problem and add a close()
 method to Blob. I'm not in favor of adding a similar method to
 ArrayBuffer at this time and therefore not to Transferable. There is a
 high-level goal to keep the typed array specification as minimal as
 possible, and having Transferable support leak in to the public
 methods of the interfaces contradicts that goal.

 I think there's broad enough consensus amongst vendors to table the
 discussion about adding close to Transferable.

 Would you please let me know why ypu believe ArrayBuffer should not have
 a close method?

 I would like some clarity here. The Typed Array spec would not be
 cluttered by the addition of a simple close method.

 It's certainly a matter of opinion -- but while it's only the addition
 of one method, it changes typed arrays' semantics to be much closer to
 manual memory allocation than they currently are. It would be a
 further divergence in behavior from ordinary ECMAScript arrays.

 The TC39 working group, I have heard, is incorporating typed arrays
 into the language specification, and for this reason I believe extreme
 care is warranted when adding more functionality to the typed array
 spec. The spec can certainly move forward, but personally I'd like to
 check with TC39 on semantic changes like this one. That's the
 rationale behind my statement above about preferring not to add this
 method at this time.


 Searching through the net tells me that this has been a rumor for years.

Regardless of rumors I have talked to multiple members of TC39 who
have clearly stated it is being incorporated into ES6 Harmony.

 I agree with taking extreme care -- so let's isolate one more bit of
 information:

 Is ArrayBuffer being proposed for TC39 incorporation, or is it only the
 Typed Arrays? The idea here is to alter ArrayBuffer, an object which can be
 neutered via transfer map. It seems a waste to have to create a Worker to
 close down buffer views.

Both ArrayBuffer and the typed array views will be incorporated.

 Will TC39 have anything to say about the neuter concept and/or Web
 Messaging?

This is an excellent question and one which I've also posed to TC39. I
don't see how the language spec could reference these concepts. I'm
guessing that this is an area that TC39 hasn't yet figured out,
either.

 Again, I'm bringing this up for the same practical experience that
 Blob.close() was brought up. I do appreciate that read/write allocation is a
 separate semantic from write-once/read-many allocation.

 I certainly don't want to derail the introduction of Typed Array into TC39.
 I don't want to sit back for two years either, while the ArrayBuffer object
 is in limbo.

Understood and appreciated.

 If necessary, I'll do some of the nasty test work of creating a worker
 simply to destroy buffers, and report back on it.
 var worker = new Worker('trash.js');
 worker.postMessage(null,[bufferToClose]);
 worker.close();
 vs.
 bufferToClose.close();

I doubt that that will work. Garbage collection will still need to run
in the worker's JavaScript context in order for the transferred
ArrayBuffer to be cleaned up, and I doubt that happens eagerly upon
shutdown of the worker. Would be happy to be proven wrong.

If you prototype adding ArrayBuffer.close() in your open source
browser of choice and report back on significant efficiency
improvements in a real-world use case, that would be valuable
feedback.

-Ken



Re: [FileAPI] Deterministic release of Blob proposal

2012-03-07 Thread Eric U
On Tue, Mar 6, 2012 at 5:12 PM, Feras Moussa fer...@microsoft.com wrote:
 From: Arun Ranganathan [mailto:aranganat...@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

RE: [FileAPI] Deterministic release of Blob proposal

2012-03-07 Thread Feras Moussa
 Then let's try this again.

 var a = new Image();
 a.onerror = function() { console.log(Oh no, my parent was neutered!); }; 
 a.src = URL.createObjectURL(blob); blob.close();

 Is that error going to hit?
I documented this in my proposal, but in this case the URI would have 
been minted prior to calling close. The Blob URI would still resolve 
until it has been revoked, so in your example onerror would not be hit 
due to calling close.

 var a = new Worker('#');
 a.postMessage(blob);
 blob.close();

 Is that blob going to make it to the worker?
SCA runs synchronously (so that subsequent changes to mutable values 
in the object don't impact the message) so the blob will have been 
cloned prior to close. 
The above would work as expected.


RE: [FileAPI] Deterministic release of Blob proposal

2012-03-07 Thread Feras Moussa
 -Original Message-
 From: Anne van Kesteren [mailto:ann...@opera.com] 
 Sent: Wednesday, March 07, 2012 12:49 AM
 To: Arun Ranganathan; Feras Moussa
 Cc: Adrian Bateman; public-webapps@w3.org; Ian Hickson
 Subject: Re: [FileAPI] Deterministic release of Blob proposal

 On Wed, 07 Mar 2012 02:12:39 +0100, Feras Moussa fer...@microsoft.com
 wrote:
  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.

 Reasonable or not, would fail is not something we can put in a standard.  
 What happens exactly? What if a connection is established and data is being 
 transmitted already?
In the case where close was called on a Blob that is being used in a 
pending request, then the request should be canceled. The expected 
result is the same as if abort() was called.


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-07 Thread Charles Pritchard

On 3/7/12 3:56 PM, Feras Moussa wrote:

Then let's try this again.

var a = new Image();
a.onerror = function() { console.log(Oh no, my parent was neutered!); }; 
a.src = URL.createObjectURL(blob); blob.close();

Is that error going to hit?

until it has been revoked, so in your example onerror would not be hit
due to calling close.

var a = new Worker('#');
a.postMessage(blob);
blob.close();

The above would work as expected.


Well that all makes sense; so speaking for myself, I'm still confused 
about this one thing:



 xhr.send(blob);
 blob.close(); // method name TBD



 In our implementation, this case would fail. We think this is reasonable 
because the



So you want this to be a situation where we monitor progress events of 
XHR before releasing the blob?
It seems feasible to monitor the upload progress, but it is a little 
awkward.


-Charles



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

2012-03-06 Thread Greg Billock
On Mon, Mar 5, 2012 at 6:46 PM, Charles Pritchard ch...@jumis.com wrote:
 On 3/5/2012 5:56 PM, Glenn Maynard wrote:

 On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@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.

 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.


 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





Re: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread Eric U
After a brief internal discussion, we like the idea over in Chrome-land.
Let's make sure that we carefully spec out the edge cases, though.
See below for some.

On Fri, Mar 2, 2012 at 4:54 PM, Feras Moussa fer...@microsoft.com wrote:
 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.



 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.

What about:

XHR.send(blob);
blob.close();

or

iframe.src = createObjectURL(blob);
blob.close();

In the second example, if we say that the iframe does copy the blob,
does that mean that closing the blob doesn't automatically revoke the
URL, since it points at the new copy?  Or does it point at the old
copy and fail?

 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.



 We’ve recently implemented this in experimental builds and have seen
 measurable

 performance improvements.



 The feedback we heard from our discussions with others at TPAC regarding our

 proposal to add a close() method to the Blob interface was that objects in
 the web

 platform potentially backed by expensive resources should have a
 deterministic

 way to be released.



 Thanks,

 Feras



 [1] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/1499.html



Re: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread David Levin
It seems like this may be setting up a pattern for other dom objects which
are large (like video/audio).

When applied in this context, is close still a good verb for them?

  video.close();

dave

PS I'm trying to not bikeshed too badly by avoiding a new name suggestion
and allowing for the fact that close may be an ok name.


On Tue, Mar 6, 2012 at 12:29 PM, Eric U er...@google.com wrote:

 After a brief internal discussion, we like the idea over in Chrome-land.
 Let's make sure that we carefully spec out the edge cases, though.
 See below for some.

 On Fri, Mar 2, 2012 at 4:54 PM, Feras Moussa fer...@microsoft.com wrote:
  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.
 
 
 
  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.

 What about:

XHR.send(blob);
blob.close();

 or

iframe.src = createObjectURL(blob);
blob.close();

 In the second example, if we say that the iframe does copy the blob,
 does that mean that closing the blob doesn't automatically revoke the
 URL, since it points at the new copy?  Or does it point at the old
 copy and fail?

  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.
 
 
 
  We’ve recently implemented this in experimental builds and have seen
  measurable
 
  performance improvements.
 
 
 
  The feedback we heard from our discussions with others at TPAC regarding
 our
 
  proposal to add a close() method to the Blob interface was that objects
 in
  the web
 
  platform potentially backed by expensive resources should have a
  deterministic
 

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

2012-03-06 Thread Kenneth Russell
On Tue, Mar 6, 2012 at 12:04 PM, Greg Billock gbill...@google.com wrote:
 On Mon, Mar 5, 2012 at 6:46 PM, Charles Pritchard ch...@jumis.com wrote:
 On 3/5/2012 5:56 PM, Glenn Maynard wrote:

 On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@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 sequenceMessagePort 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 sequenceTransferable 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
 

Re: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread Arun Ranganathan
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: 

- Original Message -

 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 erro r , 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 

// AND 

frameRef.src = URL.createObjectURL(blob); 
blob.close() // method name TBD 

In my opinion, the 

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

2012-03-06 Thread Arun Ranganathan
Ken,

 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?


Specifically, you think this is not something ArrayBuffer should inherit?  If 
it's also a bad idea for MessagePort, then those are really our only two use 
cases of Transferable right now.  I'm happy to create something like a close() 
on Blob.

-- A*



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

2012-03-06 Thread Michael Nordman
Sounds like there's a good case for an explicit blob.close() method
independent of 'transferable'. Separately defining blobs to be
transferrable feels like an unneeded complexity. A caller wishing to
neuter after sending can explicit call .close() rather than relying on
more obscure artifacts of having also put the 'blob' in a
'transferrable' array.

On Tue, Mar 6, 2012 at 1:18 PM, Kenneth Russell k...@google.com wrote:
 On Tue, Mar 6, 2012 at 12:04 PM, Greg Billock gbill...@google.com wrote:
 On Mon, Mar 5, 2012 at 6:46 PM, Charles Pritchard ch...@jumis.com wrote:
 On 3/5/2012 5:56 PM, Glenn Maynard wrote:

 On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@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 sequenceMessagePort 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 sequenceTransferable 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 

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

2012-03-06 Thread Glenn Maynard
On Tue, Mar 6, 2012 at 3:18 PM, Kenneth Russell k...@google.com wrote:
 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.

I don't like this, because it loses the invariant that structured clone is
a const operation by default.  That is, if you don't explicitly specify
objects in the transfer map, structured clone guarantees that the object
you pass in won't be modified, and that (as a corollary) you can create as
many structured clones as you want.  This always works:

function(obj)
{
thread1.postMessage(obj);
thread2.postMessage(obj);
thread3.postMessage(obj);
}

With the wrapper approach, it would no longer be guaranteed to work.

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?


When would you explicitly want to disallow manually neutering a
Transferable object?

The only case I can think where it's not obviously useful is MessagePort,
but I think that will be an exceptional case and that most Transferables
will want this method.  ArrayBuffer (currently the only other Transferable)
will, of course.

On Tue, Mar 6, 2012 at 3:34 PM, Michael Nordman micha...@google.com
 wrote:

 Separately defining blobs to be transferrable feels like an unneeded
 complexity. A caller wishing to
 neuter after sending can explicit call .close() rather than relying on
 more obscure artifacts of having also put the 'blob' in a
 'transferrable' array.


You can always call close() yourself, but Blob.close() should use the
neuter mechanism already there, not make up a new one.

-- 
Glenn Maynard


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread Glenn Maynard
(I wish people wouldn't split threads.)

On Tue, Mar 6, 2012 at 2:29 PM, Eric U er...@google.com wrote:

 What about:

XHR.send(blob);
blob.close();


This is the same as:

XHR.send(arrayBuffer);
postMessage({foo: arrayBuffer}, [arrayBuffer]);

which you can already do.  Both of these should always work, because send()
synchronously makes a (logical) copy of the underlying data:

If data is a ArrayBuffer
Let the request entity body be the raw data represented by data.
If data is a Blob
Let the request entity body be the raw data represented by data.

which happens before the call returns.


 or

iframe.src = createObjectURL(blob);
blob.close();

In the second example, if we say that the iframe does copy the blob,
 does that mean that closing the blob doesn't automatically revoke the
 URL, since it points at the new copy?  Or does it point at the old
 copy and fail?


Looking at this without involving iframe:

You could define object URLs as references to a new copy of the blob.  That
would mean that if the blob is neutered while object URLs still point at
it, a copy of the blob would have to be made by the UA even though it's
transferred.

Or, object URLs could be references to the blob itself.  That means that if
the blob is neutered, existing object URLs would be implicitly revoked.

I'd suggest the former: when a Blob is passed to native APIs, make a
(logical) copy of the Blob.  More generally, I'd recommend that all native
calls which accept a Blob, like createObjectURL, make a logical copy of the
data, like XHR.send does.  It's much easier to be consistent that way.


On Tue, Mar 6, 2012 at 3:27 PM, Arun Ranganathan aranganat...@mozilla.com
 wrote:

 although this creates something to think about for MessagePort and for
 ArrayBuffer, which also implement Transferable).


close() would be useful for ArrayBuffer, too.  It's not obviously useful
for MessagePort, but doesn't seem harmful for it to inherit it if it's not
a big implementation burden.  That's better than every single
implementation of Transferable having to define this itself.

-- 
Glenn Maynard


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

2012-03-06 Thread Michael Nordman
 Separately defining blobs to be transferrable feels like an unneeded
 complexity. A caller wishing to
 neuter after sending can explicit call .close() rather than relying on
 more obscure artifacts of having also put the 'blob' in a
 'transferrable' array.


 You can always call close() yourself, but Blob.close() should use the
 neuter mechanism already there, not make up a new one.

Blobs aren't transferable, there is no existing mechanism that applies
to them. Adding a blob.close() method is independent of making blob's
transferable, the former is not prerequisite on the latter.



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

2012-03-06 Thread Kenneth Russell
On Tue, Mar 6, 2012 at 1:31 PM, Arun Ranganathan
aranganat...@mozilla.com wrote:
 Ken,

 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?


 Specifically, you think this is not something ArrayBuffer should inherit?  If 
 it's also a bad idea for MessagePort, then those are really our only two use 
 cases of Transferable right now.  I'm happy to create something like a 
 close() on Blob.

MessagePort already defines a close() operation, so there's really no
question of whether its presence is a good or bad idea there. A
close() operation seems necessary in networking style APIs.

I would be hesitant to impose a close() method on all future
Transferable types. I don't think adding one to ArrayBuffer would be a
bad idea but I think that ideally it wouldn't be necessary. On memory
constrained devices, it would still be more efficient to re-use large
ArrayBuffers rather than close them and allocate new ones.


On Tue, Mar 6, 2012 at 1:34 PM, Michael Nordman micha...@google.com wrote:
 Sounds like there's a good case for an explicit blob.close() method
 independent of 'transferable'. Separately defining blobs to be
 transferrable feels like an unneeded complexity. A caller wishing to
 neuter after sending can explicit call .close() rather than relying on
 more obscure artifacts of having also put the 'blob' in a
 'transferrable' array.

This sounds like a good idea. As you pointed out offline, a key
difference between Blobs and ArrayBuffers is that Blobs are always
immutable. It isn't necessary to define Transferable semantics for
Blobs in order to post them efficiently, but it was essential for
ArrayBuffers.

-Ken



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

2012-03-06 Thread Charles Pritchard
On Mar 6, 2012, at 2:25 PM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 6, 2012 at 1:31 PM, Arun Ranganathan
 aranganat...@mozilla.com wrote:
 Ken,
 
 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?
 
 
 Specifically, you think this is not something ArrayBuffer should inherit?  
 If it's also a bad idea for MessagePort, then those are really our only two 
 use cases of Transferable right now.  I'm happy to create something like a 
 close() on Blob.
 
 MessagePort already defines a close() operation, so there's really no
 question of whether its presence is a good or bad idea there. A
 close() operation seems necessary in networking style APIs.
 
 I would be hesitant to impose a close() method on all future
 Transferable types. I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.


By definition, Transferable objects can be neutered; we're talking about an 
explicit method for it. After that, it's up to implementers.

I prefer .close to .release. 

An ArrayBuffer using 12megs of ram is something I want to release ASAP on 
mobile.

.close would still allow for the optimization you're implying in memory mapping.





 
 
 On Tue, Mar 6, 2012 at 1:34 PM, Michael Nordman micha...@google.com wrote:
 Sounds like there's a good case for an explicit blob.close() method
 independent of 'transferable'. Separately defining blobs to be
 transferrable feels like an unneeded complexity. A caller wishing to
 neuter after sending can explicit call .close() rather than relying on
 more obscure artifacts of having also put the 'blob' in a
 'transferrable' array.
 
 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.
 

Making Blob a Transferable may simplify the structured clone algorithm; Blob an 
File would no longer be explicitly listed. Adding close to Transferable would 
simplify three different objects -- ArrayBuffer, MessagePort and Blob. In 
theory anyway.

While Blob doesn't need the transfer map optimization, it may be helpful in the 
context of web intents postMessage as it would release the Blob references from 
one window, possibly making GC a little easier. That's just a guess... But this 
thread is about enhancing the process. Seems reasonable that this would be a 
side effect.

File.close() may have implementation side effects, such as releasing read locks 
on underlying files.

-Charles


RE: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread Feras Moussa
 From: Arun Ranganathan [mailto:aranganat...@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

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

2012-03-06 Thread Feras Moussa
 -Original Message-
 From: Arun Ranganathan [mailto:aranganat...@mozilla.com]
 Sent: Tuesday, March 06, 2012 1:32 PM
 To: Kenneth Russell
 Cc: public-webapps@w3.org; Charles Pritchard; Glenn Maynard; Feras
 Moussa; Adrian Bateman; Greg Billock
 Subject: Re: Transferable and structured clones, was: Re: [FileAPI]
 Deterministic release of Blob proposal
 
 Ken,
 
  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?
 
 
 Specifically, you think this is not something ArrayBuffer should inherit?  If 
 it's
 also a bad idea for MessagePort, then those are really our only two use cases
 of Transferable right now.  I'm happy to create something like a close() on
 Blob.
 
 -- A*
We agree Blobs do not need to be transferrable, and thus it makes sense to have 
close directly on Blob, independent of being transferable.


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-06 Thread Charles Pritchard

On 3/6/12 5:12 PM, Feras Moussa wrote:


  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.



Then let's try this again.

var a = new Image();
a.onerror = function() { console.log(Oh no, my parent was neutered!); };
a.src = URL.createObjectURL(blob);
blob.close();

Is that error going to hit?

var a = new Worker('#');
a.postMessage(blob);
blob.close();

Is that blob going to make it to the worker?


-Charles



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

2012-03-06 Thread Glenn Maynard
On Tue, Mar 6, 2012 at 4:24 PM, Michael Nordman micha...@google.com wrote:

  You can always call close() yourself, but Blob.close() should use the
  neuter mechanism already there, not make up a new one.

 Blobs aren't transferable, there is no existing mechanism that applies
 to them. Adding a blob.close() method is independent of making blob's
 transferable, the former is not prerequisite on the latter.


There is an existing mechanism for closing objects.  It's called
neutering.  Blob.close should use the same terminology, whether or not
the object is a Transferable.

On Tue, Mar 6, 2012 at 4:25 PM, Kenneth Russell k...@google.com wrote:

 I would be hesitant to impose a close() method on all future
 Transferable types.


Why?  All Transferable types must define how to neuter objects; all close()
does is trigger it.

I don't think adding one to ArrayBuffer would be a
 bad idea but I think that ideally it wouldn't be necessary. On memory
 constrained devices, it would still be more efficient to re-use large
 ArrayBuffers rather than close them and allocate new ones.


That's often not possible, when the ArrayBuffer is returned to you from an
API (eg. XHR2).

 This sounds like a good idea. As you pointed out offline, a key
 difference between Blobs and ArrayBuffers is that Blobs are always
 immutable. It isn't necessary to define Transferable semantics for
 Blobs in order to post them efficiently, but it was essential for
 ArrayBuffers.


No new semantics need to be defined; the semantics of Transferable are
defined by postMessage and are the same for all transferable objects.
That's already done.  The only thing that needs to be defined is how to
neuter an object, which is what Blob.close() has to define anyway.

Using Transferable for Blob will allow Blobs, ArrayBuffers, and any future
large, structured clonable objects to all be released with the same
mechanisms: either pass them in the transfer argument to a postMessage
call, or use the consistent, identical close() method inherited from
Transferable.  This allows developers to think of the transfer list as a
list of objects which won't be needed after the postMessage call.  It
doesn't matter that the underlying optimizations are different; the visible
side-effects are identical (the object can no longer be accessed).

-- 
Glenn Maynard


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-05 Thread Arthur Barstow
Feras - this seems kinda' late, especially since the two-week pre-LC 
comment period for File API ended Feb 24.


Is this a feature that can be postponed to v.next?

On 3/2/12 7:54 PM, ext Feras Moussa wrote:


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.

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.

We’ve recently implemented this in experimental builds and have seen 
measurable


performance improvements.

The feedback we heard from our discussions with others at TPAC 
regarding our


proposal to add a close() method to the Blob interface was that 
objects in the web


platform potentially backed by expensive resources should have a 
deterministic


way to be released.

Thanks,

Feras

[1] 
http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/1499.html






RE: [FileAPI] Deterministic release of Blob proposal

2012-03-05 Thread Feras Moussa
The feedback is implementation feedback that we have refined in the past few 
weeks as we've updated our implementation. 
We're happy with it to be treated as a LC comment, but we'd also give this 
feedback in CR too since in recent weeks we've found it to be a problem in apps 
which make extensive use of the APIs.

 -Original Message-
 From: Arthur Barstow [mailto:art.bars...@nokia.com]
 Sent: Monday, March 05, 2012 12:52 PM
 To: Feras Moussa; Arun Ranganathan; Jonas Sicking
 Cc: public-webapps@w3.org; Adrian Bateman
 Subject: Re: [FileAPI] Deterministic release of Blob proposal
 
 Feras - this seems kinda' late, especially since the two-week pre-LC comment
 period for File API ended Feb 24.
 
 Is this a feature that can be postponed to v.next?
 
 On 3/2/12 7:54 PM, ext Feras Moussa wrote:
 
  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.
 
  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.
 
  We've recently implemented this in experimental builds and have seen
  measurable
 
  performance improvements.
 
  The feedback we heard from our discussions with others at TPAC
  regarding our
 
  proposal to add a close() method to the Blob interface was that
  objects in the web
 
  platform potentially backed by expensive resources should have a
  deterministic
 
  way to be released.
 
  Thanks,
 
  Feras
 
  [1]
  http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/1499.htm
  l
 





Re: [FileAPI] Deterministic release of Blob proposal

2012-03-05 Thread Glenn Maynard
On Fri, Mar 2, 2012 at 6:54 PM, Feras Moussa fer...@microsoft.com wrote:

 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.


This is exactly like the neuter concept, defined at
http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects.
I recommend using it.  Make Blob a Transferable, and have close() neuter
the object.  The rest of this wouldn't change much, except you'd say if
the object has been neutered (or has the neutered flag set, or however
it's defined) instead of if the close method has been called.

Originally, I think it was assumed that Blobs don't need to be
Transferable, because they're immutable, which means you don't
(necessarily) need to make a copy when transferring them between threads.
That was only considering the cost of copying the Blob, though, not the
costs of delayed GC that you're talking about here, so I think transferable
Blobs do make sense.

Also, the close() method should probably go on Transferable (with a name
less likely to clash, eg. neuter), instead of as a one-off on Blob.  If
it's useful for Blob, it's probably useful for ArrayBuffer and all other
future Transferables as well.

-- 
Glenn Maynard


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-05 Thread Charles Pritchard

On 3/5/2012 3:59 PM, Glenn Maynard wrote:
On Fri, Mar 2, 2012 at 6:54 PM, Feras Moussa fer...@microsoft.com 
mailto:fer...@microsoft.com wrote:


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.


This is exactly like the neuter concept, defined at 
http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects.  
I recommend using it.  Make Blob a Transferable, and have close() 
neuter the object.  The rest of this wouldn't change much, except 
you'd say if the object has been neutered (or has the neutered flag 
set, or however it's defined) instead of if the close method has 
been called.


Originally, I think it was assumed that Blobs don't need to be 
Transferable, because they're immutable, which means you don't 
(necessarily) need to make a copy when transferring them between 
threads.  That was only considering the cost of copying the Blob, 
though, not the costs of delayed GC that you're talking about here, so 
I think transferable Blobs do make sense.


Also, the close() method should probably go on Transferable (with a 
name less likely to clash, eg. neuter), instead of as a one-off on 
Blob.  If it's useful for Blob, it's probably useful for ArrayBuffer 
and all other future Transferables as well.




Glenn,

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?
blob = keepBlob; // keeping a copy of my blob still in thread.

Sorry to cover too many angles: if Blob is Transferable, then it'll 
neuter; so if we do want a local copy, we'd use slice ahead of time to 
keep it.
And we might have an error on postMessage stashing it in the transfer 
array if it's not a Transferable on an older browser.

The new behavior is pretty easy.
var blob = new Blob(my big blob);
blob.close(); // My blob has been neutered before it could procreate.

-Charles


Re: [FileAPI] Deterministic release of Blob proposal

2012-03-05 Thread Glenn Maynard
On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@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?
 blob = keepBlob; // keeping a copy of my blob still in thread.

Sorry to cover too many angles: if Blob is Transferable, then it'll neuter;
 so if we do want a local copy, we'd use slice ahead of time to keep it.


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.


 And we might have an error on postMessage stashing it in the transfer
 array if it's not a Transferable on an older browser.


It'll throw TypeError, which you'll need to handle if you need to support
older browsers.

The new behavior is pretty easy.
 var blob = new Blob(my big blob);
 blob.close(); // My blob has been neutered before it could procreate.


Sorry, I'm not really sure what you're trying to say.  This still works
when using the neutered concept; it just uses an existing mechanism, and
allows transfers.

-- 
Glenn Maynard


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

2012-03-05 Thread Charles Pritchard

On 3/5/2012 5:56 PM, Glenn Maynard wrote:
On Mon, Mar 5, 2012 at 7:04 PM, Charles Pritchard ch...@jumis.com 
mailto:ch...@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.

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.



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




Re: [FileAPI] Deterministic release of Blob proposal

2012-03-02 Thread Charles Pritchard

On 3/2/2012 4:54 PM, Feras Moussa wrote:


At TPAC we discussed the ability to deterministically close blobs with 
a few


others.



...


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.




I suppose the theory of Blob is that it can be written to disk. The 
other theory is that reference counting can somehow work magic.

I'm not sure, but it came up before.

I brought up a close mechanism for ArrayBuffer, which is (I believe) 
supposed to be in memory, always.

http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-January/029741.html

Also referenced:
http://www.khronos.org/webgl/public-mailing-list/archives/1009/msg00229.html

ArrayBuffer can now be closed out of the current thread via Transferable 
semantics.

I don't know if it disappears into space with an empty postMessage target.

I don't think that works for Blob, though.

Yes, I'd like to see immediate mechanisms to cleanup Blob and ArrayBuffer.
In practical use, it wasn't an issue on the desktop and the iPhone 
hadn't picked up the semantics yet.


But gosh it's no fun trying to navigate memory management on mobile 
device. Thus my low memory event thread.


-Charles