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