On Nov 27, 2013, at 11:18 AM, Konstantin Preißer <kpreis...@apache.org> wrote:

> Hi Dan,
> 
>> -----Original Message-----
>> From: Daniel Mikusa [mailto:dmik...@gopivotal.com]
>> Sent: Wednesday, November 27, 2013 1:48 PM
>> To: Tomcat Users List
>> Subject: Re: Another Non-blocking IO Question
>> 
>> I'm seeing another issue with the same basic test though.  After I tested the
>> previous changes and confirmed they worked, I increased the amount of
>> data that the request was sending.
>> 
>>    int rc = postUrl(true, new StaticBytesStreamer(5 * 1048576, 131072, 0),
>> "http://localhost:"; +
>>                            getPort() + "/", new ByteChunk(), resHeaders, 
>> null);
>> 
>> This uncovered a problem with my tests where I wasn't checking
>> output.isReady() and I was able to fix that.  However after fixing that I'm
>> getting another hang.
>> 
>> In this case, this is what seems to happen...
>> 
>> 1.) The test client sends 1441792 bytes of data
>> 2.) onWritePossible is called, this in turn calls onDataAvailable and starts
>> echoing data
>> 2.) The test echoer is able to read and write back 696091 bytes successfully
>> 3.) At this point there is more input to read, but the call to 
>> output.isReady()
>> returns false and the initial call to onWritePossible finishes.
>> 4.) I see a call to onDataAvailable from the container.  This checks the
>> input.isReady() which is true, but output.isReady() is still false.  The 
>> call to
>> onDataAvailable finishes.
>> 5.) This is where the test hangs.
>> 
>> At this point, I would have expected onWritePossible to be called again by
>> the container, since calls to output.isReady() returned false.  I haven't had
>> much luck debugging this further.
>> 
>> Here's the updated test case.
>> 
>>   https://gist.github.com/dmikusa-pivotal/7660005
>> 
>> Any thoughts?
> 
> I'm not an expert in using non-blocking I/O with Servlet 3.1, but I can see 
> two possible issues with your test case:
> 
> 1) Your test directly copies the ServletInputStream to the 
> ServletOutputStream using a buffer of 8 KB. Are you sure that the HTTP client 
> which you use for uploading the data is reading the response while still 
> sending the request?
> 
> As far I can see, you are using TomcatBaseTest#postUrl() [1]. Having a quick 
> look at this method, it first writes the complete request body before 
> starting the response. This would explain the hang as the client is not 
> reading from the response body, and Tomcat is not able to write to the 
> response, causing a Deadlock.
> 
> This also happened when I tried this with Firefox: It would wait until the 
> request is completely written before starting to read the response. (I would 
> think that generally a HTTP client can not be expected to simultaneously read 
> the response and write the request.)

I had a similar thought, so I'm glad to hear you mention it as well.  I'll 
definitely have to investigate further.

Thanks

Dan

> 
> 
> 2) If I read correctly, when onAllDataRead() is called, you call 
> asyncContext.complete(); without checking if sos.isReady() is true. This 
> could mean that the AsyncContext is completed before the last call to 
> sos.write() has finished. When I tried this with Tomcat's NumberWriter 
> example, this meant that the browser did not receive all data - the last 8 KB 
> block was missing. When I changed the code to check if sos.isReady() before 
> completing the AsyncContext (and if it is false, wait for the next call to 
> onWritePossible before completing), then the browser received all of the sent 
> data.
> 
> However, I do not know what the required behavior here is. Tomcat's 
> ByteCounter example also directly calls ac.complete() after writing to the 
> response without checking sos.isReady(), but because it is just a few bytes 
> it probably is able to completely write the bytes before sos.write() returns, 
> do it doesn't have practical consequences.
> 
> 
> Regards,
> Konstantin Preißer
> 
> 
> [1] 
> http://svn.apache.org/repos/asf/tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to