Re: [XHR2] why have an asBlob attribute at all?
On 10/28/10 5:22 PM, David Flanagan wrote: In fact, I'd go further and ask why the blob case needs to be special cased at all. The bytes are stored somewhere. Returning them as a blob doesn't seem any harder than returning them as an ArrayBuffer. David, the issue is that if you make a request for a 4GB resource and ask for it as an array buffer and you're on a 32-bit system, the only thing the browser can do is throw an out of memory exception. On the other hand, if you access the same response as a blob, the browser can let you do that; you just won't be able to get it all into a single JS string. So there are definitely use cases for being able to access as a Blob. I know that Blobs are an outgrowth of the File API, but won't many Blobs (created by BlobBuilders, for example) be in-memory objects rather than on-disk objects? I believe BlobBuilder can stick the data anywhere it wants. And shouldn't the decision about whether to spool a response to disk or not be implementation-dependent? It is, yes. But we still need an API that doesn't force the response into memory in its entirety. and then memory map it to make it look like it is in memory. That doesn't help for the truly large responses; the OS won't let you memory map them in its entirety... (Probably because I'm missing something fundamental about the nature of Blobs... I'd love to know what it is!) The key part with a blob is that you can access parts of it without forcing the whole thing into the process's address space. -Boris
Re: [XHR2] why have an asBlob attribute at all?
On 10/28/2010 06:24 PM, Boris Zbarsky wrote: On 10/28/10 5:22 PM, David Flanagan wrote: In fact, I'd go further and ask why the blob case needs to be special cased at all. The bytes are stored somewhere. Returning them as a blob doesn't seem any harder than returning them as an ArrayBuffer. David, the issue is that if you make a request for a 4GB resource and ask for it as an array buffer and you're on a 32-bit system, the only thing the browser can do is throw an out of memory exception. On the other hand, if you access the same response as a blob, the browser can let you do that; you just won't be able to get it all into a single JS string. Thanks for the explanation, Boris. The L in Blob is an order of magnitude larger than anything I was imagining. Now I understand why both Blobs and ArrayBuffer are required. I still don't get, however, why the API needs distinct blob/non-blob modes. Why not do it like this: - The implementation decides whether to store the response in a file or not based on its own knowledge of the Content-Length and of the system's hardware. (And perhaps the developer can set some kind of reallyBig flag as a hint that the implementation should consider saving the response to disk.) - The response body is always available through responseBlob. No special asBlob flag is required. - If the response is too big to fit in memory, then accessing responseText, responseArrayBuffer or responseXML will throw an out-of-memory exception. This is what would happen if you naively tried to use the FileReader interface on the un-sliced Blob, so why can't that happen here? With the API as it is now, a web developer who wants to download a gigantic chunk of data has to know in advance to use a blob to avoid the possibility of out-of-memory errors. They have to put their XHR object into a special asBlob mode in order to do so. And once they ar in that mode if they try to use responseText or responseArrayBuffer, they're guaranteed to get a INVALID_STATE_ERR exception at runtime. With my proposal, the developer still has to know in advance that they probably ought to use a blob. But they don't have to set a special flag to do it. And if they do use responseText or responseArrayBuffer, they might get an out-of-memory error at runtime, but there's also a decent chance that things will just work (maybe with some disk swapping slowing things down a bit). I doubt I understand all the implementation issues. But if there really is some reason to have this blob/non-blob decision point before calling send(), can I suggest that instead of confusing the XHR API with it, it be moved into a separate BlobHttpRequest interface that has only reponseBlob and does not even define responseText, etc. David
Re: [XHR2] why have an asBlob attribute at all?
On Fri, 29 Oct 2010 07:55:58 +0200, David Flanagan wrote: I doubt I understand all the implementation issues. But if there really is some reason to have this blob/non-blob decision point before calling send(), can I suggest that instead of confusing the XHR API with it, it be moved into a separate BlobHttpRequest interface that has only reponseBlob and does not even define responseText, etc. Brainstorming here. We could choose to always expose resonseArrayBuffer and keep it together with responseText and responseXML. And for applications that are worried about memory usage or care about very large files we could have BlobXMLHttpRequest similar to AnonXMLHttpRequest. We'd abstract some things out from XMLHttpRequest so BlobXMLHttpRequest does not have the other response* members and so that AnonXMLHttpRequest does not need withCredentials and the fourth and fifth parameter to open(). -- Anne van Kesteren http://annevankesteren.nl/
Re: [XHR2] why have an asBlob attribute at all?
On Fri, Oct 29, 2010 at 4:08 AM, Anne van Kesteren wrote: > On Fri, 29 Oct 2010 07:55:58 +0200, David Flanagan > wrote: >> >> I doubt I understand all the implementation issues. But if there really >> is some reason to have this blob/non-blob decision point before calling >> send(), can I suggest that instead of confusing the XHR API with it, it be >> moved into a separate BlobHttpRequest interface that has only reponseBlob >> and does not even define responseText, etc. > > Brainstorming here. We could choose to always expose resonseArrayBuffer and > keep it together with responseText and responseXML. And for applications > that are worried about memory usage or care about very large files we could > have BlobXMLHttpRequest similar to AnonXMLHttpRequest. We'd abstract some > things out from XMLHttpRequest so BlobXMLHttpRequest does not have the other > response* members and so that AnonXMLHttpRequest does not need > withCredentials and the fourth and fifth parameter to open(). Could we, um, not include the word "XML" in any new things? BlobHttpRequest seems much less silly. ~TJ
Re: [XHR2] why have an asBlob attribute at all?
On Fri, 29 Oct 2010 13:08:07 +0200, Anne van Kesteren wrote: Brainstorming here. We could choose to always expose resonseArrayBuffer and keep it together with responseText and responseXML. And for applications that are worried about memory usage or care about very large files we could have BlobXMLHttpRequest similar to AnonXMLHttpRequest. We'd abstract some things out from XMLHttpRequest so BlobXMLHttpRequest does not have the other response* members and so that AnonXMLHttpRequest does not need withCredentials and the fourth and fifth parameter to open(). Nevermind, then we'd need AnonBlobXMLHttpRequest too for completeness. Not so great. -- Anne van Kesteren http://annevankesteren.nl/
Re: [XHR2] why have an asBlob attribute at all?
On 10/29/2010 06:07 AM, Anne van Kesteren wrote: > On Fri, 29 Oct 2010 13:08:07 +0200, Anne van Kesteren > wrote: >> Brainstorming here. We could choose to always expose >> resonseArrayBuffer and keep it together with responseText and >> responseXML. And for applications that are worried about memory usage >> or care about very large files we could have BlobXMLHttpRequest >> similar to AnonXMLHttpRequest. We'd abstract some things out from >> XMLHttpRequest so BlobXMLHttpRequest does not have the other response* >> members and so that AnonXMLHttpRequest does not need withCredentials >> and the fourth and fifth parameter to open(). > > Nevermind, then we'd need AnonBlobXMLHttpRequest too for completeness. > Not so great. > Too bad. If you were okay with BlobHttpRequest and AnonBlobHttpRequest, I was going to propose BufferHttpRequest and AnonBufferHttpRequest as well. If adding a responseType flag would break jQuery, and not adding responseType would double the memory usage of all XHR requests, then it seems like defining a new API is the way out of the dilemma. So if I can continue the brainstorm... Note that a new BufferHttpRequest need not be binary-only. It can still have a decodeResponseAsText() method or something equivalent. And it creates the opportunity to get rid of XML in the name! Why can't the Anon part be taken care of with a constructor parameter? (And is there any value in putting other things in the constructor like a cross-origin flag and the withCredentials flag?) XMLHttpRequest(anon): has today's responseText and responseXML properties only. (Is there a case for anonymous legacy XHR at all?) BufferHttpRequest(anon): has a single response property that is an ArrayBuffer. For convenience, it also has a responseAsText property that decodes the buffer to text when read. (Purposely avoiding "responseText" so legacy code that checks responseText.length can't be ported to BufferHttpRequest) BlobHttpRequest(anon): has a single response property that is a Blob. Of course defining a BufferHttpRequest type really invites a StreamingHttpRequest as well, and I have the suspicion that a streaming API solves a more fundamental problem than Blobs do... David