W3C home > Mailing lists > Public > public-webapi@w3.org > February 2007

Re: Progress Use Cases (was Re: Progress event spec)

From: Maciej Stachowiak <mjs@apple.com>
Date: Tue, 6 Feb 2007 04:09:31 -0800
Message-Id: <05C1AD18-382C-41CE-BE86-03703DCFD040@apple.com>
Cc: Web API public <public-webapi@w3.org>
To: Charles McCathieNevile <chaals@opera.com>


On Feb 5, 2007, at 10:19 PM, Charles McCathieNevile wrote:

> The progress and uploadprogress events are optional events that can  
> be fired by
> (for an example) a user agent in the middle of an XmlHttpRequest (XHR)
> transaction. The start and end of that transaction (whether  
> successfully or in
> some error condition) are, in this example, predefined parts of XHR.

The use case I presented was a reusable progress display control that  
can connect to any possible event target that is a source of progress  
events. Do you deny the validity of this use case, or do you have a  
proposed alternate design that satisfies it?

I am confident that the spec as currently written does not satisfy  
it, and I think you would agree, since you suggest the use of out-of- 
band information specific to the particular kind of event target to  
drive the UI correctly.

> In terms of Media Access Events, it corresponds to the  
> DataReceptionProgress
> event.
>
> It may never fire.

If it's valid for the event to never fire, or to fire arbitrarily in  
the middle of the load but not at the start or end, that makes it  
much harder to use effectively in a way that works across  
implementations. If one implementation sends start and end progress  
events, and another doesn't, it is highly likely that code only  
tested in one will fail in the other. I think interoperability is  
more important than ease of implementing the spec in limited-resource  
browsers.

> If you want to be compatible with the web, you can trap the
> start and end of an existing load. Since you have no progress  
> information and
> don't know how long it will take, set up an indeterminate activity  
> indicator
> like a spinning wheel or barber pole. If a progress event fires,  
> and provides
> information you can use to determine more accurately the progress,  
> then you can
> change the state of your indicator to reflect the new information  
> (as you would
> anyway, no?). If you never get one, you can silently vanish, flash  
> your bar full
> first, put a statement that you got an object of foo size (which  
> you determine
> by measuring it) or whatever else makes you happy.

Given the EventTarget interface, how do you measure the size of the  
relevant object? Or for that matter, how do you measure the size in  
bytes of the contents of an <img> element, or a parsed DOM document  
in a frame, or the contents of an <svg:image>, or the contents of an  
<object> tag handled by a plugin, even if you know the exact kind of  
object you are dealing with?

> If it is necessary to disambiguate the case where the size of the  
> transfer is
> unknown, but has "begun" although no data has been received, from  
> the case where
> there is zero data to be transferred and the transfer has begun,  
> but not yet
> completed then requiring that a progress event MUST not fire for a  
> zero-length
> transfer makes sense. I have no strong opinion on that. Following  
> my assertion
> that you have the load starting, you set up an indeterminate  
> indicator, it
> finishes, and if you like you flash full and close. Why should  
> Opera Mini have
> to send the extra events to tell you nothing happened, and why  
> should authors
> write extra code to look for them anyway (unless they are ignoring  
> the existing
> load that they get today).

Can you please tell me what events would fire when in the several  
examples I posted? It is much easier to have clarity on whether the  
API works if you explain how it applies to different cases in detail,  
as I did for my proposal. Note that my examples were not contrived,  
but were based on how various progress tracking APIs and UI elements  
work in a real web browser. I assume we want web content to be able  
to give an equally good experience.

I also don't understand why you are so insistent on using 0 length to  
indicate indeterminate length rather than having a separate boolean  
attribute for this with a clear name. In-band signalling is generally  
considered poor API design. Even if this approach were not unworkable  
it would lead to less clear user code [if (event.total != 0) vs if  
(event.totalIsKnown) or the like].

>
> On Thu, 01 Feb 2007 08:18:45 +0530, Maciej Stachowiak  
> <mjs@apple.com> wrote:
>
>>
> ...
>> As you can see, to cover all the use cases, "loadstart", a "progress"
>> event at the beginning, a "progress" event at the end, and "load" are
>> all needed and serve different purposes. And you need the boolean to
>> in "progress" to tell you whether the length is determinate or not.
>> You cannot overload these for the following reasons:
>>
>> 1) You can't combine "progress" [0,0,true] and "progress" [0,0,false]
>> because: then you don't know whether to flash full (many progress UIs
>> like to flash the completed progress bar for at least a moment) or to
>> switch to the indeterminat progress bar.
>
> Why do you need start and end events to trigger this? And are you  
> going to rely
> on some perceivable time gap between the progress and the load (or  
> error or...)
> to set the timing of this flash?

These aren't start and end events - the idea here was that you need  
to tell the difference between 0 bytes so far, 0 total, load  
complete; and 0 bytes so far, unknown total. If you never send a  
progress event for the former case, how can you tell the size? See  
above for why "measure it" is not a valid answer. And you can't just  
assume it is 0 if you got no progress events, since after all you  
might be in a UA that doesn't support progress events at all, or only  
sends them during a full moon, since this would apparently apparently  
be conformant.

>
>> 2) You can't combine "loadstart" with "progress" [0,?,?] because: You
>> want to start showing feedback the moment loading starts, even if no
>> server response has yet told you what the content length will be, or
>> whether it is determinate, but you want to show the total or reflect
>> that it is unknown the moment that is the case.
>
> When loading starts you almost certainly don't know the total. If  
> we outlaw
> progress events for zero-length transfers, you get it as [0,0] and  
> it is clear
> you still don't know the total. Alternatively you may get [0,X] and  
> can set up
> the determinate version before you start. But why would you rely on  
> this anyway?

I think you misunderstood my point, which was that you want to  
display the total as soon as it is know (or certain to be unknown) at  
the first progress event. This progress event may be 0 bytes in  
length, or more, but will probably be sent as soon as the  
implementation receives the http header or similar.

>
>> 3) You can't combine the final "progress" with "load" because: if you
>> only have "load", there's no way to know the final total of bytes in
>> the indeterminate case,
>
> This is true, if you can't measure the thing you loaded. What is  
> the use case
> for that?

Already stated - reusable progress control. Say I have my <html:img>  
element firing progress events. How do I "measure the thing [I've]  
loaded" in that case? If we are designing this API solely for the use  
of XHR then it should be in XMLHttpRequest 2.0, not a separate spec.  
If it is meant to be reusable, then it should be designed to be  
complete.

>
>> and if you only have the final "progress",
>> you can never tell in the indeterminate case that the load has
>> finished. After all, "load" may never happen, you could get "error"
>> instead.
>
> Assuming the error is a fatal one, that should be a clear  
> indication that you
> have reached some end, no? Maybe we could come up with a way of  
> programming
> where you try to do something, but have a way of catching errors as  
> well as
> success...

This clause meant to explain why the final "load" event can't be  
omitted, even if you require a final "progress" event that shows the  
final amount of bytes read.

>
>> How the "error" and "loadcancel" events would fit in is left as an
>> excercise to the reader; I hope it is obvious that you would need it
>> to have a working progress UI driven solely by events, which I think
>> is a desirable goal.
>
> I suspect we disagree at the level of where we think the effort  
> should be in UI
> construction. (I can also imagine a use case where there is no UI,  
> and you use
> the progress events to dynamically optimise some set of network  
> operations).
> While both of us are talking about a UI driven solely by events, I  
> believe that
> you can readily build a UI with fewer of them, and that this has  
> the added
> benefit of forcing you to build one that is a bit more backwards- 
> compatible with
> the web as it already is.

I'd like to see your specific proposal for what these events are and  
how you should use them. I also think new APIs designed by the Web  
API WG should be easy to use correctly, and should not require  
guesses about what different user agents might do. Vagueness in  
written standards is what leads to de facto standards by mutual  
reverse engineering.

>> It may sound overengineered to have so many
>> events, but it's the only way to make it possible to build correct  
>> UI.
>
> We have some of these events already in whatever specification (XHR  
> is an
> example) is going to use progress events. I believe that relying on  
> those makes
> it possible to build correct UI.

It may be possible to build an XHR-only one, although I do not think  
you have demonstrated even that. It should be very easy to copy my  
charts and annotate them with what event is guaranteed to happen  
when, and what the UI does in response to it. I am quite certain that  
you can't build one which can be attached to any plausible progress  
event target.

Consider also the XHR upload case, there is no obvious way to get the  
total size of what you uploaded if it is a serialized DOM document   
for instance. You could serialize it in what you hope is the same was  
as XHR would do it, but this is not certain to be correct, and it is  
quite expensive to do an extra serialization just to get the length  
of the string. Plus, even then, you don't know the length of the  
contents sent

It seems much simpler to have an obviously complete set of progress  
events than to play tricks with what you might be able to do with  
fewer in some cases. What is the case against completeness?

Regards,
Maciej
Received on Tuesday, 6 February 2007 12:10:03 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 8 January 2008 14:18:57 GMT