RE: FileReader abort, again

2012-03-06 Thread Feras Moussa
> Anne confirmed that a new open in onerror or onload /would/ suppress the 
> loadend of the first send.  
>So we would want a new read/write in onload or onerror to do the same, not 
>just those in onabort.
We encountered this same ambiguity in the spec, and we agree with the above. 
This is also what we 
have implemented and shipped in the consumer preview.

> Hack 2: Add a virtual generation counter/timestamp, not exposed to 
> script.  Increment it in read*, check it in abort before sending 
> loadend.  This is kind of complex, but works [and might be how I end 
> up implementing this in Chrome].
Of the list of 'hacks', we also implemented hack #2 to get the correct behavior.



> -Original Message-
> From: Eric U [mailto:er...@google.com]
> Sent: Tuesday, March 06, 2012 12:16 PM
> To: Arun Ranganathan
> Cc: Web Applications Working Group WG
> Subject: Re: FileReader abort, again
> 
> On Mon, Mar 5, 2012 at 2:01 PM, Eric U  wrote:
> > On Thu, Mar 1, 2012 at 11:20 AM, Arun Ranganathan
> >  wrote:
> >> Eric,
> >>
> >>> >> > So we could:
> >>> >> > 1. Say not to fire a loadend if onloadend or onabort
> >>>
> >>> Do you mean "if onload, onerror, or onabort..."?
> >>
> >>
> >> No, actually.  I'm looking for the right sequence of steps that results in
> abort's loadend not firing if terminated by another read*.  Since abort will 
> fire
> an abort event and a loadened event as spec'd
> (http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort), if *those* event
> handlers initiate a readAs*, we could then suppress abort's loadend.  This
> seems messy.
> >
> > Ah, right--so a new read initiated from onload or onerror would NOT
> > suppress the loadend of the first read.  And I believe that this
> > matches XHR2, so we're good.  Nevermind.
> 
> No, I retract that.  In
> http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/1627.html
> Anne confirmed that a new open in onerror or onload /would/ suppress the
> loadend of the first send.  So we would want a new read/write in onload or
> onerror to do the same, not just those in onabort.
> 
> >>> Actually, if we really want to match XHR2, we should qualify all the
> >>> places that we fire loadend.  If the user calls XHR2's open in
> >>> onerror or onload, that cancels its loadend.  However, a simple
> >>> check on readyState at step 6 won't do it.  Because the user could
> >>> call readAsText in onerror, then call abort in the second read's
> >>> onloadstart, and we'd see readyState as DONE and fire loadend twice.
> >>>
> >>> To emulate XHR2 entirely, we'd need to have read methods dequeue
> any
> >>> leftover tasks for previous read methods AND terminate the abort
> >>> algorithm AND terminate the error algorithm of any previous read
> >>> method.  What a mess.
> >>
> >>
> >> This may be the way to do it.
> >>
> >> The problem with emulating XHR2 is that open() and send() are distinct
> concepts in XHR2, but in FileAPI, they are the same.  So in XHR2 an open()
> canceling abort does make sense; abort() cancels a send(), and thus an
> open() should cancel an abort().  But in FileAPI, our readAs* methods are
> equivalent to *both* open() and send().  In FileAPI, an abort() cancels a
> readAs*; we now have a scenario where a readAs* may cancel an
> abort().  How to make that clear?
> >
> > I'm not sure why it's any more confusing that read* is open+send.
> > read* can cancel abort, and abort can cancel read*.  OK.
> >
> >
> >>> Perhaps there's a simpler way to say "successfully calling a read
> >>> method inhibits any previous read's loadend"?
> >>
> >> I'm in favor of any shorthand :)  But this may not do justice to each
> readAs* algorithm being better defined.
> >
> > Hack 1: Don't call loadend synchronously.  Enqueue it, and let read*
> > methods clear the queues when they start up.  This differs from XHR,
> > though, and is a little odd.
> 
> Still works, but needs to be applied in multiple places.
> 
> > Hack 2: Add a virtual generation counter/timestamp, not exposed to
> > script.  Increment it in read*, check it in abort before sending
> > loadend.  This is kind of complex, but works [and might be how I end
> > up implementing this in Chrome].
> 
> 
> Still works, but needs to be applied in multiple places.
> 
> > But really, I don't think either of those is better than just saying,
> > in read*, something like "terminate the algorithm for any abort
> > sequence being processed".
> 
> ...or any previously-initiated read being processed.
> 





Re: FileReader abort, again

2012-03-06 Thread Eric U
On Mon, Mar 5, 2012 at 2:01 PM, Eric U  wrote:
> On Thu, Mar 1, 2012 at 11:20 AM, Arun Ranganathan
>  wrote:
>> Eric,
>>
>>> >> > So we could:
>>> >> > 1. Say not to fire a loadend if onloadend or onabort
>>>
>>> Do you mean "if onload, onerror, or onabort..."?
>>
>>
>> No, actually.  I'm looking for the right sequence of steps that results in 
>> abort's loadend not firing if terminated by another read*.  Since abort will 
>> fire an abort event and a loadened event as spec'd 
>> (http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort), if *those* event 
>> handlers initiate a readAs*, we could then suppress abort's loadend.  This 
>> seems messy.
>
> Ah, right--so a new read initiated from onload or onerror would NOT
> suppress the loadend of the first read.  And I believe that this
> matches XHR2, so we're good.  Nevermind.

No, I retract that.  In
http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/1627.html
Anne confirmed that a new open in onerror or onload /would/ suppress
the loadend of the first send.  So we would want a new read/write in
onload or onerror to do the same, not just those in onabort.

>>> Actually, if we really want to match XHR2, we should qualify all the
>>> places that we fire loadend.  If the user calls XHR2's open in
>>> onerror
>>> or onload, that cancels its loadend.  However, a simple check on
>>> readyState at step 6 won't do it.  Because the user could call
>>> readAsText in onerror, then call abort in the second read's
>>> onloadstart, and we'd see readyState as DONE and fire loadend twice.
>>>
>>> To emulate XHR2 entirely, we'd need to have read methods dequeue any
>>> leftover tasks for previous read methods AND terminate the abort
>>> algorithm AND terminate the error algorithm of any previous read
>>> method.  What a mess.
>>
>>
>> This may be the way to do it.
>>
>> The problem with emulating XHR2 is that open() and send() are distinct 
>> concepts in XHR2, but in FileAPI, they are the same.  So in XHR2 an open() 
>> canceling abort does make sense; abort() cancels a send(), and thus an 
>> open() should cancel an abort().  But in FileAPI, our readAs* methods are 
>> equivalent to *both* open() and send().  In FileAPI, an abort() cancels a 
>> readAs*; we now have a scenario where a readAs* may cancel an abort().  How 
>> to make that clear?
>
> I'm not sure why it's any more confusing that read* is open+send.
> read* can cancel abort, and abort can cancel read*.  OK.
>
>
>>> Perhaps there's a simpler way to say "successfully calling a read
>>> method inhibits any previous read's loadend"?
>>
>> I'm in favor of any shorthand :)  But this may not do justice to each 
>> readAs* algorithm being better defined.
>
> Hack 1: Don't call loadend synchronously.  Enqueue it, and let read*
> methods clear the queues when they start up.  This differs from XHR,
> though, and is a little odd.

Still works, but needs to be applied in multiple places.

> Hack 2: Add a virtual generation counter/timestamp, not exposed to
> script.  Increment it in read*, check it in abort before sending
> loadend.  This is kind of complex, but works [and might be how I end
> up implementing this in Chrome].


Still works, but needs to be applied in multiple places.

> But really, I don't think either of those is better than just saying,
> in read*, something like "terminate the algorithm for any abort
> sequence being processed".

...or any previously-initiated read being processed.



Re: FileReader abort, again

2012-03-05 Thread Eric U
On Thu, Mar 1, 2012 at 11:20 AM, Arun Ranganathan
 wrote:
> Eric,
>
>> >> > So we could:
>> >> > 1. Say not to fire a loadend if onloadend or onabort
>>
>> Do you mean "if onload, onerror, or onabort..."?
>
>
> No, actually.  I'm looking for the right sequence of steps that results in 
> abort's loadend not firing if terminated by another read*.  Since abort will 
> fire an abort event and a loadened event as spec'd 
> (http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort), if *those* event handlers 
> initiate a readAs*, we could then suppress abort's loadend.  This seems messy.

Ah, right--so a new read initiated from onload or onerror would NOT
suppress the loadend of the first read.  And I believe that this
matches XHR2, so we're good.  Nevermind.

>
>>
>> Actually, if we really want to match XHR2, we should qualify all the
>> places that we fire loadend.  If the user calls XHR2's open in
>> onerror
>> or onload, that cancels its loadend.  However, a simple check on
>> readyState at step 6 won't do it.  Because the user could call
>> readAsText in onerror, then call abort in the second read's
>> onloadstart, and we'd see readyState as DONE and fire loadend twice.
>>
>> To emulate XHR2 entirely, we'd need to have read methods dequeue any
>> leftover tasks for previous read methods AND terminate the abort
>> algorithm AND terminate the error algorithm of any previous read
>> method.  What a mess.
>
>
> This may be the way to do it.
>
> The problem with emulating XHR2 is that open() and send() are distinct 
> concepts in XHR2, but in FileAPI, they are the same.  So in XHR2 an open() 
> canceling abort does make sense; abort() cancels a send(), and thus an open() 
> should cancel an abort().  But in FileAPI, our readAs* methods are equivalent 
> to *both* open() and send().  In FileAPI, an abort() cancels a readAs*; we 
> now have a scenario where a readAs* may cancel an abort().  How to make that 
> clear?

I'm not sure why it's any more confusing that read* is open+send.
read* can cancel abort, and abort can cancel read*.  OK.


>> Perhaps there's a simpler way to say "successfully calling a read
>> method inhibits any previous read's loadend"?
>
> I'm in favor of any shorthand :)  But this may not do justice to each readAs* 
> algorithm being better defined.

Hack 1: Don't call loadend synchronously.  Enqueue it, and let read*
methods clear the queues when they start up.  This differs from XHR,
though, and is a little odd.
Hack 2: Add a virtual generation counter/timestamp, not exposed to
script.  Increment it in read*, check it in abort before sending
loadend.  This is kind of complex, but works [and might be how I end
up implementing this in Chrome].

But really, I don't think either of those is better than just saying,
in read*, something like "terminate the algorithm for any abort
sequence being processed".

Eric



Re: FileReader abort, again

2012-03-01 Thread Arun Ranganathan
Eric,

> >> > So we could:
> >> > 1. Say not to fire a loadend if onloadend or onabort 
> 
> Do you mean "if onload, onerror, or onabort..."?


No, actually.  I'm looking for the right sequence of steps that results in 
abort's loadend not firing if terminated by another read*.  Since abort will 
fire an abort event and a loadened event as spec'd 
(http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort), if *those* event handlers 
initiate a readAs*, we could then suppress abort's loadend.  This seems messy.


> 
> Actually, if we really want to match XHR2, we should qualify all the
> places that we fire loadend.  If the user calls XHR2's open in
> onerror
> or onload, that cancels its loadend.  However, a simple check on
> readyState at step 6 won't do it.  Because the user could call
> readAsText in onerror, then call abort in the second read's
> onloadstart, and we'd see readyState as DONE and fire loadend twice.
> 
> To emulate XHR2 entirely, we'd need to have read methods dequeue any
> leftover tasks for previous read methods AND terminate the abort
> algorithm AND terminate the error algorithm of any previous read
> method.  What a mess.


This may be the way to do it.

The problem with emulating XHR2 is that open() and send() are distinct concepts 
in XHR2, but in FileAPI, they are the same.  So in XHR2 an open() canceling 
abort does make sense; abort() cancels a send(), and thus an open() should 
cancel an abort().  But in FileAPI, our readAs* methods are equivalent to 
*both* open() and send().  In FileAPI, an abort() cancels a readAs*; we now 
have a scenario where a readAs* may cancel an abort().  How to make that clear?

 
> Perhaps there's a simpler way to say "successfully calling a read
> method inhibits any previous read's loadend"?

I'm in favor of any shorthand :)  But this may not do justice to each readAs* 
algorithm being better defined. 

-- A*



Re: FileReader abort, again

2012-02-29 Thread Eric U
On Wed, Feb 29, 2012 at 2:57 PM, Arun Ranganathan
 wrote:
>> On Wed, Feb 29, 2012 at 1:43 PM, Arun Ranganathan
>> >> Otherwise, if you start a new read in onabort [8.5.6 step 5],
>> >> you'll
>> >> still deliver the loadend [8.5.6 step 6].
>> >> This contradicts 8.5.9.2.1 "Once a loadstart has been fired, a
>> >> corresponding loadend fires at completion of the read, EXCEPT if
>> >> the
>> >> read method has been cancelled using abort() and a new read method
>> >> has
>> >> been invoked."
>> >
>> > This seems like familiar ground, and I'm sorry this contradiction
>> > still exists.
>> >
>> > So we could:
>> >
>> > 1. Say not to fire a loadend if onloadend or onabort re-initiate a
>> > read.  But this may be odd in terms of analyzing a program before.

Do you mean "if onload, onerror, or onabort..."?

>> > 2. Simply not fire loadend on abort.  I'm not sure this is a good
>> > idea.

Agreed.  It should be there unless another read starts.

>> > What's your counsel?  Have I missed something easier?
>> >
>> > -- A*
>>
>> My email must have crossed yours mid-flight, but just in case, how
>> about speccing that read* methods terminate the abort algorithm?
>> That's what XHR2 does, and it looks like it works.  It's not the
>> easiest thing to figure out when reading the spec.  It took me a
>> while
>> to get my mind around it in XHR2, but then that's a much more
>> complicated spec.  FileReader's small enough that I think it's not
>> unreasonable, and of course matching XHR2 means fewer surprises all
>> around.
>
>
> OK, I'll study XHR2 and figure this out.  Spec'ing this isn't a quick win, 
> though, since abort's role is to terminate a read*!  So to have a 
> re-initiated read* terminate an abort will require some thought on invocation 
> order.

I don't see a conflict--abort terminates read, and read terminates abort.

Actually, if we really want to match XHR2, we should qualify all the
places that we fire loadend.  If the user calls XHR2's open in onerror
or onload, that cancels its loadend.  However, a simple check on
readyState at step 6 won't do it.  Because the user could call
readAsText in onerror, then call abort in the second read's
onloadstart, and we'd see readyState as DONE and fire loadend twice.

To emulate XHR2 entirely, we'd need to have read methods dequeue any
leftover tasks for previous read methods AND terminate the abort
algorithm AND terminate the error algorithm of any previous read
method.  What a mess.

Perhaps there's a simpler way to say "successfully calling a read
method inhibits any previous read's loadend"?

[steps 5 and 6 there are missing trailing periods, BTW]



Re: FileReader abort, again

2012-02-29 Thread Arun Ranganathan
> On Wed, Feb 29, 2012 at 1:43 PM, Arun Ranganathan
> >> Otherwise, if you start a new read in onabort [8.5.6 step 5],
> >> you'll
> >> still deliver the loadend [8.5.6 step 6].
> >> This contradicts 8.5.9.2.1 "Once a loadstart has been fired, a
> >> corresponding loadend fires at completion of the read, EXCEPT if
> >> the
> >> read method has been cancelled using abort() and a new read method
> >> has
> >> been invoked."
> >
> > This seems like familiar ground, and I'm sorry this contradiction
> > still exists.
> >
> > So we could:
> >
> > 1. Say not to fire a loadend if onloadend or onabort re-initiate a
> > read.  But this may be odd in terms of analyzing a program before.
> >
> > 2. Simply not fire loadend on abort.  I'm not sure this is a good
> > idea.
> >
> > What's your counsel?  Have I missed something easier?
> >
> > -- A*
> 
> My email must have crossed yours mid-flight, but just in case, how
> about speccing that read* methods terminate the abort algorithm?
> That's what XHR2 does, and it looks like it works.  It's not the
> easiest thing to figure out when reading the spec.  It took me a
> while
> to get my mind around it in XHR2, but then that's a much more
> complicated spec.  FileReader's small enough that I think it's not
> unreasonable, and of course matching XHR2 means fewer surprises all
> around.


OK, I'll study XHR2 and figure this out.  Spec'ing this isn't a quick win, 
though, since abort's role is to terminate a read*!  So to have a re-initiated 
read* terminate an abort will require some thought on invocation order.

-- A*



Re: FileReader abort, again

2012-02-29 Thread Eric U
On Wed, Feb 29, 2012 at 1:43 PM, Arun Ranganathan
 wrote:
> FileReader.abort is like a bad penny :)
>
>
>>
>> However, I'm not sure it quite matches the normative text in one
>> respect.  Where you say [8.5.6 step 4]: "Terminate any steps while
>> processing a read method."  Does that also terminate the steps
>> associated with an abort that terminated the read method?  Basically
>> I'm not sure what "steps while processing a read method" means.
>
> I've changed this to terminate only the read algorithm (and hopefully it is 
> clear this isn't the same as the abort steps):
>
> http://dev.w3.org/2006/webapi/FileAPI/#terminate-an-algorithm and
>
>
>
>>
>> Otherwise, if you start a new read in onabort [8.5.6 step 5], you'll
>> still deliver the loadend [8.5.6 step 6].
>> This contradicts 8.5.9.2.1 "Once a loadstart has been fired, a
>> corresponding loadend fires at completion of the read, EXCEPT if the
>> read method has been cancelled using abort() and a new read method
>> has
>> been invoked."
>
> This seems like familiar ground, and I'm sorry this contradiction still 
> exists.
>
> So we could:
>
> 1. Say not to fire a loadend if onloadend or onabort re-initiate a read.  But 
> this may be odd in terms of analyzing a program before.
>
> 2. Simply not fire loadend on abort.  I'm not sure this is a good idea.
>
> What's your counsel?  Have I missed something easier?
>
> -- A*

My email must have crossed yours mid-flight, but just in case, how
about speccing that read* methods terminate the abort algorithm?
That's what XHR2 does, and it looks like it works.  It's not the
easiest thing to figure out when reading the spec.  It took me a while
to get my mind around it in XHR2, but then that's a much more
complicated spec.  FileReader's small enough that I think it's not
unreasonable, and of course matching XHR2 means fewer surprises all
around.

Eric



Re: FileReader abort, again

2012-02-29 Thread Arun Ranganathan
FileReader.abort is like a bad penny :)


> 
> However, I'm not sure it quite matches the normative text in one
> respect.  Where you say [8.5.6 step 4]: "Terminate any steps while
> processing a read method."  Does that also terminate the steps
> associated with an abort that terminated the read method?  Basically
> I'm not sure what "steps while processing a read method" means.

I've changed this to terminate only the read algorithm (and hopefully it is 
clear this isn't the same as the abort steps): 

http://dev.w3.org/2006/webapi/FileAPI/#terminate-an-algorithm and



> 
> Otherwise, if you start a new read in onabort [8.5.6 step 5], you'll
> still deliver the loadend [8.5.6 step 6].
> This contradicts 8.5.9.2.1 "Once a loadstart has been fired, a
> corresponding loadend fires at completion of the read, EXCEPT if the
> read method has been cancelled using abort() and a new read method
> has
> been invoked."

This seems like familiar ground, and I'm sorry this contradiction still exists.

So we could:

1. Say not to fire a loadend if onloadend or onabort re-initiate a read.  But 
this may be odd in terms of analyzing a program before.

2. Simply not fire loadend on abort.  I'm not sure this is a good idea.

What's your counsel?  Have I missed something easier?

-- A*



Re: FileReader abort, again

2012-02-29 Thread Eric U
Incidentally, the way XHR gets around this is to have open cancel any
in-progress abort.  We could certainly do the same thing, having any
readAs* cancel abort().

On Tue, Feb 28, 2012 at 4:15 PM, Eric U  wrote:
> I like the Event Invariants writeup at the end.  It's only
> informative, but it is, indeed, informative.
>
> However, I'm not sure it quite matches the normative text in one
> respect.  Where you say [8.5.6 step 4]: "Terminate any steps while
> processing a read method."  Does that also terminate the steps
> associated with an abort that terminated the read method?  Basically
> I'm not sure what "steps while processing a read method" means.
>
> Otherwise, if you start a new read in onabort [8.5.6 step 5], you'll
> still deliver the loadend [8.5.6 step 6].
> This contradicts 8.5.9.2.1 "Once a loadstart has been fired, a
> corresponding loadend fires at completion of the read, EXCEPT if the
> read method has been cancelled using abort() and a new read method has
> been invoked."
>
>        Eric [copying this into FileWriter]