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