Hello Remy,

Over the weekend I was thinking of a state machine (a simple one would be
sufficient though). The client API will upload/send the header. After this
he will go to upload the body, but is constantly checking (in a different
thread?) if the response is already send. I the response is completely send,
the upload will be terminated and the response will be processed.

A simple solution could be to check (when the IOException is arrived), if
the response is completely received: in this case return the response, else
redo the action, for something else happened.

What do you think?

Juergen



 -----Original Message-----
From:   Remy Maucherat [mailto:[EMAIL PROTECTED]] 
Sent:   Friday, July 13, 2001 10:15 PM
To:     [EMAIL PROTECTED]
Subject:        Re: Slide with Tomcat 3.3

Quoting "Pill, Juergen" <[EMAIL PROTECTED]>:

> Hello,
> 
> I think I found a problem with Slide and Tomcat 3.3 (it should also
> occur in
> Tomcat 3.2 for for some reason it does not).
> 
> Scenario:
> 
> A file is locked (e.g. by word) and an other user (e.g. an application
> using
> the slide client API) wants to overwrite this file. In this case the
> second
> user (over writer) will try to put the files multiple times (up to 5)
> until
> he prints an exception (if the Slide client API is used):
> 
> Reopen connection : Host:localhost Port:8080
> 
> 
> HTTP/1.0 423
> Closing connection
> Reopen connection : Host:localhost Port:8080
> 
> 
> HTTP/1.0 423
> Closing connection
> Reopen connection : Host:localhost Port:8080
> 
> 
> HTTP/1.0 423
> Closing connection
> Reopen connection : Host:localhost Port:8080
> 
> 
> HTTP/1.0 423
> Closing connection
> Reopen connection : Host:localhost Port:8080
> 
> 
> HTTP/1.0 423
> Closing connection
> Reopen connection : Host:localhost Port:8080
> org.apache.commons.httpclient.HttpException: Unable to process request
>         at
>
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:606)
>         at
>
com.softwareag.xtools.xdav.testtools.tprocessor.TProcessors.executeStep(TPro
> cessors.java:376)
>         at
>
com.softwareag.xtools.xdav.testtools.tprocessor.TProcessors.exceuteStepOrRep
> eater(TProcessors.java:299)
>         at
>
com.softwareag.xtools.xdav.testtools.tprocessor.TProcessors.executeTestCase(
> TProcessors.java:266)
>         at
>
com.softwareag.xtools.xdav.testtools.tprocessor.TProcessors.mainExecuter(TPr
> ocessors.java:142)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.MultiTProcessorExecuter$1.job(Mu
> ltiTProcessorExecuter.java:50)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.DirectoryWalker.walkDirectory(Di
> rectoryWalker.java:65)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.DirectoryWalker.walkDirectory(Di
> rectoryWalker.java:69)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.DirectoryWalker.walkDirectory(Di
> rectoryWalker.java:69)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.DirectoryWalker.<init>(Directory
> Walker.java:30)
>         at
>
com.softwareag.xtools.xdav.testtools.walker.MultiTProcessorExecuter.exceuteA
> llSpecifiedXMLFileByTProcessor(Mult
>         at
>
com.softwareag.xtools.xdav.testtools.walker.MultiTProcessorExecuter.main(Mul
> tiTProcessorExecuter.java:62)
> 
> 
> 
> The problem lies in following code snipplet:
> 
> 
>       public synchronized void executeMethod(HttpMethod method)
>               throws IOException, HttpException {
> 
>               int retries = 0;
> 
>               Hashtable responseHeaders = null;
> 
>               boolean methodProcessed = false;
>               boolean sentRequestBody = false;
> 
>               openConnection();
> 
>               while ((retries < 5) && (!methodProcessed)) {
> 
>                       try {
> 
>                               responseHeaders = null;
>                               sentRequestBody = false;
> 
>                               // Send the request header except if the
>                               byte[] query = sendRequestHeader(method);
> 
>                               if ((!http11) ||
> (!method.needExpectation())) {
>                                       sendRequestBody(method, query);
>                                       sentRequestBody = true;
>                               }
> 
> 
> The server will start to process the request when the header is sent.
> The
> request can be completely executed by the header infos only, and the
> server
> closes that request, including the associated sockets. Thus sending the
> body
> will lead to an IOException, which will redo this scenario until the
> retries
> condition holds.
> 
> Does this make sense? (if yes, Remy, will you do the necessary
> changes?)

Yes, this does make sense.

I don't know how to fix it reliably if the server is not HTTP/1.1 (and uses
the 
continue correctly - Tomcat 4 still doesn't, for example).
We could choose not to retry if there is an IOException while uploading the 
request body.

One of the main problem is that if the request is successful, the response
will 
only get sent after the end of the upload. If there's a lock problem, the 
response is sent immediately (and recieved a random amount of time later by
the 
client, along with a disconnect, usually).

Ideas welcome :)

Remy

Reply via email to