« Return to Thread: File upload progress

RE: File upload progress

by mikewse :: Rate this Message:

Reply to Author | View in Thread

Jose wrote:

On Tue, Jun 9, 2009 at 8:04 PM, Mike Wilson <mikewse@...> wrote:
 
About a potentially unset scriptSessionId (because of a fresh page), I think the following behaviour could be appropriate:
 
Default upload:
Remote.uploadFile(dwr.util.byId("myFile"), 
{
    callback: ...,
    progressCallback:  ... 
});
 
Here the default ScriptSession-based incovationId is used, so the client layer needs to know the scriptSessionId before sending along the upload, as we would otherwise not know what invocationId to poll progress about.
Thus, if scriptSessionId has not yet been set we need to send a pre-flight call that retrieves this id (this is always done by the first call from a fresh page, f ex by reverse Ajax polls when using that mode). After the return of that request we can then start the real upload request.
I have to disagree here. This adds server load for nothing in return.  
We are usually on the same page when it comes to saving requests so I'll try to convince you here ;-).
If you think back on our discussion about static engine.js quite a long time ago, I think you will agree with me. In 2.x engine.js contains the scriptSessionId and has to be delivered "fresh" for every page. For 3.0 Joe first changed this so engine.js was static, but an extra request was then sent on every page load to fetch the scriptSessionId. You and I wanted to avoid the extra request so we instead devised a solution where the scriptSessionId is unknown until the first (user-triggered) call goes to the server. We then had to avoid that two requests were sent in parallel as long as the scriptSessionId was unknown, as this would otherwise create two different ids for the same page. That's why engine.js starts up in ordered mode until it has the scriptSessionId.
 
Now, the whole thing of progress handling is about sending two requests in parallel. One long request that we want to monitor, and many small ones to get the progress. If the calls would start in parallel before we have a scriptSessionId then they will connect to different script sessions. Note that to avoid this, currently engine.js delays one of the calls until the first one returns (="ordered mode").
 
I question the effect of additional server load that you mention; you are about to send maybe 20-30 extra requests just to update a progress bar and you are concerned about avoiding one request to "initialize the progress handling", if needed?
And the extra request will only need to be sent IFF we are actually watching progress for this operation, and IFF there has not been any other request already sent from this page (unlikely), and IFF the user code is using the script session based upload.
Keep in mind that the invocationId has not to be unique (at least for file upload and even more so with a session manager).
The "total" fingerprint of the invocationId must be unique, but depending on the server-side manager you will automatically have it "prefixed" or "scoped" (this is just logical reasoning and doesn't mean there is any string concat going on):
 
ScriptSessionManager: scriptSessionId + invocationId(=batchId)
SessionManager: JSESSIONID + invocationId
ApplicationManager: invocationId
 
For the script session case it is enough to use a sequentially incremented invocationId, as we are guaranteed that we are the only page with this scriptSessionId.
For the session case we may be several browser windows/tabs sharing the same JSESSIONID, so a simple increment is not enough.
For the application case (shudder), we need to provide an invocationId that is globally unique over all user sessions on the site, to avoid interference between users.
 
Maybe the real point you are making is that we shouldn't be using the scriptSessionId based version at all, and focus on the other variants. If we do, then we have to adapt for the hardest one, which is the application based, as we (currently) in the client layer don't know which manager they're using.
Providing a guaranteed globally unique id generated in the client is something Joe looked a lot at for script sessions, and he didn't want to risk the consequences of doing it.
This is why I think we by default should reuse the global id we already have (scriptSessionId), and avoid inventing a new ad-hoc id. User code can override it when not using the default implementation.
 
But then again, if you can provide a guaranteed globally unique id generation algorithm for the client, then we could improve script session handling in general instead...
I remember from a previous discussion that it was suggested that progress could be delivered by Reverse Ajax, if active on the page. I'm not sure how much that would complicate things.

I think that reverse ajax polls are less frequent than what is required to update a progress widget. The two could be combined in the future but I'm not going to attempt this at this stage. 
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.

Reverse AJAX should be optional in any case. And I'm not sure I see the benefits of RA here though given that the polling only lasts as long as the file upload.
Certainly, I'm not saying we should implement RA progress handling. But it has been discussed before and I don't remember the arguments. Anybody can fill in?
A contrived case would be hitting the two-connection limit when doing
- reverse ajax streaming connection
- file upload
- progress calls as normal (non-RA) calls
at the same time (you can't have all three of them).
 
Best regards
Mike

 « Return to Thread: File upload progress