----- Original Message ----- From: "Andrew Hill" <[EMAIL PROTECTED]> To: "Struts Users Mailing List" <[EMAIL PROTECTED]> Sent: Wednesday, September 10, 2003 3:18 AM Subject: RE: What's the best strategy to handle this kind of thread issues?
> My undertsanding was that the browser will only show the response to the the > second of the requests - forgetting about the first. The server of course > hasnt forgetten about it and keeps processing (one hopes). Im not quite sure > what happens to its response stream (>>null?) but the browser is now only > waiting for the second requests response - which I presume is a seperate > connection? It is very likely for the browser window to use the same connection to send request A and B (with the keep alive setting). But I am not 100% sure for this. Any Tomcat users or experts could provide some clue? > > Now if we are using tokens or some such mechanism to detect that its a > second request and thus illigitimate then we can of course return some kind > of error to the user instead of processing the request (since we know its > already been processed). Assume the token is used. Thread B returns error messages. But thread A is still valid in the processing mode. When thread A returns with response A, the difficulty here is the browser window could *ignore* response A. If the browser window shows response A, it is much better. > > This however isnt very friendly. What we really want to do is to have the > second request return the same response as would have been returned by the > first request after it did its work. I have no practical solution for this > :-( I have the same expectation and am considering using the very first filter to 1) block other threads or 2) render the pending contents from thread A. But we have real challenging issues here as you see my comments below. > > Hmm. Actually I have an idea. Not a good one, but maybe worth a passing > thought: > (Thinking off the top of my head here btw (and the following will not work > in a distributed environment unless one has sticky sessions so that all > requests for a particular session are gauranteed to be processed by the same > JVM)): > > 0. Requests A,B,C,N come in in rapid succession and cause threads to be > started in the container to process the requests - probably but not > necessarily in the order they came in. > > 1. Thread B (or any other thread) is lucky enough to start running first > and. Synchronizing on some global object (probably its own Class object if > its a singleton) it checks the session for a token (under a key that was > generated earlier and submitted as a request param in a hidden field). Not > finding it, it creates it and stores it in the session, and proceeds to > marshall the data needed to render a response - whatever it is the action is > supposed to actually do. > > 2. Threads A,C,N also sync on the global object and check the session. > Unlike thread B, they find the token, so they all call wait() on the token > object. > > 3. Having doing the processing & read/updated the db (or whatever), and > obtained the necessary info, etc... Thread B is finally ready to render a > response. It doesnt know however if it is the 'lucky last' thread that the > browser is actually waiting for. What it does then is to add the necessary > information to render the response to the session (perhaps the token could > provide getters for it?), and having done so it calls notifyAll() on the > token object, and then proceeds itself to forward to the view. > This could open a bad time window for other threads to modify data models while thread B is rendering the view. > 4. Threads A,C,N are woken up by the notify(), and proceed to grab the > necessary info from the session to render the same response that B is now > rendering and forward to the view. (NB: we shall assume that the view (jsp > or velocity template or whatever *only* renders the view and doesnt change > any of the information is uses to render the view (with one notable > exception) - and that that info can be read by multiple threads at once!). > One of these 4 threads is the lucky one (N in this example) that will > actually have their response output on the browser. 3 of them are wasting > time rendering to nowhere - but they are all rendering identical html, and > the user will get an appropriate response page instead of an error. > We could not assume thread A,C,or N are to render the same response as B. They could have different handling logic. > 5. After they have finished rendering and flushed the 4 threads all try to > remove the token from the session. (You will note that if another request > comes in at this point we are in trouble. We could of course leave the token > in the session along with all the response data just in case but then we > would run out of memory after a while... (maybe we could use some kind of > self expiring cache? hmmm)) This "removing/resetting a token form the session" mechanism is not guaranteed to work. For example, when thread B is rendering its view, a runtime exception is thrown, then who is responsible to remove/reset the token in the session or call notifyAll() on the token object? A timed token could remove/reset itself as you suggested. It is a common misconception to think using transaction token is going to solve *all* of our problems. We have introduced a Form Token Facility in Netspread Carrier to automatically protect every web form and link. But it has the *holes* to handle multiple threads from a single user. I also checked Java Server Faces Specification. It does not say anything about it (or maybe I miss it somewhere). Swing solves it using a single event dispatch thread. Could someone point out to us why Faces does not address it or where it is addressed? Things are not always *that* simple as they appear to us :-) I have said we are *sloppy* users, are we? Jing Netspread Carrier http://www.netspread.com --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]