W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2009

Re: File API Feedback

From: Garrett Smith <dhtmlkitchen@gmail.com>
Date: Wed, 8 Jul 2009 14:26:32 -0700
Message-ID: <c9e12660907081426m2d2c8827i2f46da0a5c2b5c34@mail.gmail.com>
To: Jonas Sicking <jonas@sicking.cc>
Cc: arun@mozilla.com, Boris Zbarsky <bzbarsky@mit.edu>, Ian Hickson <ian@hixie.ch>, Anne van Kesteren <annevk@opera.com>, WebApps WG <public-webapps@w3.org>
On Mon, Jul 6, 2009 at 1:38 PM, Jonas Sicking<jonas@sicking.cc> wrote:
> On Wed, Jul 1, 2009 at 9:01 PM, Garrett Smith<dhtmlkitchen@gmail.com> wrote:
>> On Tue, Jun 30, 2009 at 7:36 PM, Jonas Sicking<jonas@sicking.cc> wrote:
>>> On Tue, Jun 30, 2009 at 6:13 PM, Garrett Smith<dhtmlkitchen@gmail.com> wrote:
>>>> On Tue, Jun 30, 2009 at 4:29 PM, Jonas Sicking<jonas@sicking.cc> wrote:
>>>>> On Tue, Jun 30, 2009 at 4:22 PM, Garrett Smith<dhtmlkitchen@gmail.com> wrote:
>>>>>>> With that in mind, do you still think it makes sense to have progress
>>>>>>> events and all the other events you are proposing?
>>>>>>
>>>>>> I've reread my message. The arguments and reasoning given for Events
>>>>>> seem clear and concise. The argument for Progress Events was
>>>>>> illustrated with an example and a comparison. What was confusing?
>>>>>
>>>>> What is the use case for the API you are proposing?
>>>>
>>>> The program wants to attach more than one "success" callback at places
>>>> in the code. The program wants to attach a "timeout" callback, to
>>>> handle cases where the read operation is too slow.
>>>
>>> But *why* would someone want to attach more than one success callback?
>>
>> Why would someone want to attach more than one "click" handler to
>> document? It doesn't really matter why, but it is not hard to imagine
>> situations.
>>
>> For example, a notification for all success reads of files to notify
>> the user of "done", but then specific notifications about the current
>> file read. Not hard to imagine, but, AISB, it is not necessary to
>> consider all possible contexts. You have snipped and ignored that and
>> all other questions. Please don't do that.
>>
>> AISB, "An asynchronous file read is like an asynchronous XHR, in a
>> way." It can be desirable to want to have more than one callback for
>> XHR.
>
> I don't know that I've ever seen someone attach more than one
> eventhandler to an XHR request. In fact, I'm not even sure that IE
> supports more than one. For the longest time firefox didn't, and I
> don't think I ever saw a request for attaching more than one.
>

Multiple callbacks for XHR are facilitated by custom events. That was
explained in the "<ajax library aside>" that I wrote.

> Similarly, any API for file access that I have ever seen has only used
> a single callback. And file system APIs have existed for many many
> years.
>
> UI handling is a lot different from file handling so I don't think the
> analogy with the "click" event is that strong. The only similarity is
> the use of a callback.
>

The user interacts with the file upload mechanism inside the browser. See?

> So again, can you give an example of where you'd like two listeners
> notified with data read from the file?
>

What was wrong with the first time I posted it?

Scroll back up and read:
| For example, a notification for all success reads of files to notify...

Read the entire paragraph. Think, write, revise, etc.

>> The requirement that determines "inordinately long" comes from a
>> human, or humans. It is realized in code via a timeout mechanism to
>> cancel the call. This is prevalent in code that must perform
>> asynchronously e.g. XHR, animations, etc.
>>
>> MSDN's XHR and XDR documentation[1] has an example of timeout that is
>> of particular relevance here; XHR is a data request over http,
>> FileUpload is a data request in the local network. It is a very common
>> pattern to have a timeout[2]. Even progress events has a timeout event
>> (shoehorned into "error")[3].
>
> If we add a cancelPendingReads() function (or whatever we decide to
> call it) then the following code would work to implement timeouts:
>
> myFile.dataAsText(dataCallback, errorCallback);
> timer = setTimeout(function() { myFile.cancelPendingReads(); }, 10000);
>
> function dataCallback(data) {
>  cancelTimeout(timer);
>  ... do stuff with data ...
> }
>

Yes, using a timeout is very common for code that must perform async,
AISB. I didn't spell it out with a setTimeout example. It seemed
obvious.

The hypothetical example is missing a var declaration, though.

>
> The two use cases for the timeout property on XDR are:
>
> 1. When using synchronous requests. In this case the timeout code
> above doesn't work since timers don't fire during synchronous reads.
> 2. As a more convenient API than the above.
>

Yes, that one.

>
> 1 doesn't apply to the file API since there are no synchronous
> requests. As for use case 2, I'm not convinced that timeouts for local
> file reads are common enough that we need to add convenience APIs to
> deal with it. Especially not in the first revision of the spec.
>

I see. Do you anticipate that timeouts will become more common in the
second revision?

> However if others think it's important, we could add a .timeout
> property on the File object. This would cancel any reads that took
> longer than the set time and call the error callback.

Is this a straw poll? I hope not. That sounds like "appeal to
popularity" and *that* would probably be dilatory.

Reasoned arguments can and should be assessed aside from the person
posing them. Reasoned arguments might help avoid generalizing, appeal
to *, and ad hominem and may help elucidate valuable insight in the
mind of the readers (the majority of whom will not post their
thoughts).

You've already stated that you have objections to a timeout property.
If you have an opinion on a timeout property, why don't you state it?

>
>>> And it gets worse if you want to read the data both as raw data and as
>>> a data-url. For example in order to process the raw data and send it
>>> to the server, as well as use the data-url to display a preview using
>>> an <img>. In that case the code would be more something like:
>>>
>>> file.onsuccess = handleDataUrl;
>>> file.onerror = genericError;
>>> file.readAsDataURL();
>>>
>>> function handleDataUrl() {
>>>  ...
>>>  file.onsuccess = handleTextDatal;
>>>  file.readAsText();
>>> }
>>>
>>
>> Spaghetti code.
>>
>> The documentation for FileDialog[0] has named the callback parameter
>> to getAsDataURI as "FileAsText ". From the editor's draft:
>>
>> | getAsDataURI(in FileAsText callback, [Optional] in FileErrorCallback
>> errorCallback);
>>
>> Your example raises a good point. There are two reads, each with
>> different behavior, but callbacks are a shared behavior. Why not have
>> a Reader for each behavior?
>>
>>  var reader = file.textReader;
>>  reader.success = textReadSuccess;
>>  reader.read();
>>
>>  reader = file.uriReader;
>>  reader.success = uriReadSuccess;
>>  reader.read();
>>
>> That makes the individual callbacks a lot simpler. It also provides a
>> "read" interface that works on any type of Reader. It really makes
>> more sense when you think about it; a File does not read; a Reader
>> does.
>
> So what if you're reading two parts of the file and want different
> callbacks. Say for example that you're reading data out of a video
> file and you want to read both the index of the video to see how long
> it is, as well as read read the first frame in order to display a
> preview. Once we have an API for reading ranges of a file, you'd do:
>
> file.getDataAtRange(0, 1024, indexHandler, genericError);
> file.getDataAtRange(4711, 5735, indexHandler, genericError);
>
> (the example assumes that the index is located at byte 0, and the
> first video frame is located at byte 4711).
>
> How would you do that using the API you are proposing?

I wrote a straw man for a Reader, which could use the Events API. In
the example, a Reader was obtained from a file.

  var reader = file.textReader;
  reader.read( file );

I see you did not respond to that.

That proposal may have some problems. The role of a File originally
included behavior to read itself. I changed that to give the file a
"reader" property. From a role perspective, that's still a bit off.
Why should a file "have" a reader? Why cannot a Reader exist on its
own? That way, it can be passed a File to read, and some other
arguments.

Example:

  reader.read( file );

and for ranges:-

  reader.read( file[, start, end);

Your question:-
"How would you do that using the API you are proposing?"

Use an event handler on the Reader. For example:-
if(typeof FileReader != "undefined" && "BINARY" in FileReader) {
  reader = FileReader.create( FileReader.BINARY );
  if(reader != null) { // Reader was created.
    reader.addEventListener("success", func, false);
    reader.read(file, i, j);
  }
}

Wrinkly, maybe but the gist.


Messages I have posted in this thread raised points and questions that
your message follow-ups have ignored and/or snipped. AISB, and again,
please don't do that.

Regards,

Garrett
Received on Wednesday, 8 July 2009 21:27:15 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:32 GMT