« Return to Thread: File upload progress

RE: File upload progress

by mikewse :: Rate this Message:

Reply to Author | View in Thread

Lance wrote:

2009/6/9 Mike Wilson <mikewse@...>
Lance wrote:
2009/6/7 Mike Wilson <mikewse@...>
Lance wrote:  
dwr.engine.cancelUpload("myUpload");
</javascript>

engine.js generates an invocationId which is passed to the server which can be used to cancel an upload or poll it's current progress.
2) Generic progress and cancellation
As you mentioned in an earlier mail, it could be interesting to provide a generic progress/cancellation mechanism for all calls, not just for file uploads. I then think it would be natural to return an object from any async call following the Deferred/Future pattern. This object could be used for asking about progress, completion status or to trigger cancellation, and would replace (but possibly contain) the invocationId in your example.
If providing progress for all kinds of requests, then we can not depend on always getting a percentage to the progress callback, as we typically don't know the size of outbound data. The parameters could instead be designed this way:
function(transferredBytes, totalBytes)
and the totalBytes would only be set in the cases when we do have that information (and could easily be converted to a percentage). When totalBytes is undefined, a progress dialog could still show the running transferredBytes count.

Hmm... this locks us into a file upload now rather than a more generic process percentage. I'm not 100% on this but could be talked into it. 
My point was actually the opposite, ie not to lock us into file upload ;-).
Normally, it is only at upload (file or data) that we know the total number of bytes we are going to send and can thus calculate the percentage. If we want to use generic progress handling for large sets of outbound data ("download") then we normally don't know the total size at it is processed in a streaming fashion. This makes the percentage impossible to calculate for this case, and therefore I suggested the "transferred byte count so far" to be used in the progress callback.
 
Also, I believe that it could be interesting for the progress indicator to be able, at will, to show the byte count and not just the percentage. Percentages can easily be derived from the bytes if the total is available.

By generic I am talking about for all long running tasks, not necessarily involving bytes. I've seen a really good implementation of a progress indicator where processes were able to return strings stating which stage they were at. A progress manager would after a while collect the results of the same process and would be able to estimate the percentage complete on the current stage and previous results. It's not perfect but the progress widget moved quite steadily after it had collected a big enough survey. Food for thought anyway.  
I'm all for something that is compatible with as many cases as possible. The problem I was seeing with the "percentage" suggestion was that we have no way to solve it for outbound data in DWR, but it is always easy to count bytes.
 
I see how you mean that a "learning" progress manager could use heuristics and historical data to guess a percentage. This is quite advanced functionality though, and will probably not show up in trunk anytime soon. But I like the idea of making it possible.
 
The progress manager based on process stage sounds more like something you integrate with application code, ie it is non-DWR code on the server-side that delivers the progress information. This is probably an interesting future use-case if we go for generic progress handling, so it could well get to influence some of the current design decisions.
 
I'm fine with the use-cases you've suggested and it would great to make an API that could cater for the different needs presented.
To sum up, it seems like in some use-cases we have a byte count but no percentage, and in others we have a percentage but no byte count. I think the byte count, when applicable, is valuable for some use-cases ("Uploaded 5.7MB of 12MB") so maybe we should have an API that can work with both bytes and percentages?
I think the goal in that previous discussion was to use reverse ajax in streaming mode so updates are transmitted immediately, but within the same request. Ie, a single poll and then pushing progress from the server into the poll request's response stream every 500ms or whatever has been set. This certainly doesn't have to be implemented now, but it would be good if you could take a quick look to see if it will be possible to add this feature within the current public APIs we are designing now.

I must say that my knowlege of how comet works is more theoretical than practical. Can you lead me towards some of the classes you'd like me to take a look at? 
Oh, you probably don't have to look so much at how it is implemented as long as you have the general idea of it. The thing is that it would probably work the other way around, ie the timer loop that triggers each progress transmission would sit on the server. Each time it triggers it would ask about progress in the server, and then push a progress method call, maybe something like:
dwr.engine.remote.handleProgress(batchId, progressinfo...)
to the client through the reverse ajax channel.
The handleProgress method would then call the appropriate progressCallbacks registered on the batch.
 
Best regards
Mike

 « Return to Thread: File upload progress