Thanks for the excellent pointer to the pitfalls of using Aync IO! Unfortunately my problem still remains even after I allocate a new buffer for each iteration.
Thanks, Michael On Tue, Apr 14, 2015 at 11:16 AM, Joakim Erdfelt <[email protected]> wrote: > Looking at your code ... > > private void synchronized doWrite() throws IOException > { > _buffer.flip(); > byte[] tmpBuf = new byte[4096]; > while(_os.isReady() && _buffer.hasRemaining()) > { > int bytesNum = Math.min(tmpBuf.length, _buffer.remaining()); > _buffer.get(tmpBuf, 0, bytesNum); <-- if this is the second > iteration, you can't do this, you don't tmpBuf anymore > _os.write(tmpBuf, 0, bytesNum); <-- first use of tmpBuf is now > "in-process" > } > _buffer.compact(); > } > > The behavior of Async I/O is tricky to manage. > See Simone's excellent talk/slides at > http://www.slideshare.net/SimoneBordet/servlet-31-async-io > > The problem lies in your changing of the tmpBuf within the loop. > The first call to _os.write(tmpBuf, 0. bytesNum) means that buffer now > belongs to Jetty. > You can't change that buffer in the second iteration of the the loop. > You'd need a new buffer each iteration of the loop. > > > -- > Joakim Erdfelt <[email protected]> > webtide.com <http://www.webtide.com/> - intalio.com/jetty > Expert advice, services and support from from the Jetty & CometD experts > eclipse.org/jetty - cometd.org > > On Tue, Apr 14, 2015 at 1:54 PM, Michael Aaron <[email protected]> > wrote: > >> Hello, >> >> I have upgraded to jetty-all-9.2.10.v20150310, but the problem remains. >> What might be wrong? Does this exception mean usage error (my code >> attempting to write when isReady() is not true), or does this mean some >> internal problem of Jetty? >> >> Thanks, >> Michael >> >> On Mon, Apr 13, 2015 at 4:08 PM, Joakim Erdfelt <[email protected]> >> wrote: >> >>> Can you try again with at least 9.2.9? >>> >>> There's been a great deal of work (bug fixes and improvements) in the >>> state management of Async I/O with that release. >>> >>> Note that jetty 9.2.10 is also available. >>> >>> Also, more importantly, Jetty 9.2.7 is considered a vulnerable release, >>> security wise >>> <https://github.com/eclipse/jetty.project/blob/master/advisories/2015-02-24-httpparser-error-buffer-bleed.md> >>> . >>> >>> >>> -- >>> Joakim Erdfelt <[email protected]> >>> webtide.com <http://www.webtide.com/> - intalio.com/jetty >>> Expert advice, services and support from from the Jetty & CometD experts >>> eclipse.org/jetty - cometd.org >>> >>> On Mon, Apr 13, 2015 at 4:00 PM, Michael Aaron <[email protected]> >>> wrote: >>> >>>> Hello, >>>> >>>> I'm using Async IO feature of Jetty 9 (9.2.7.v20150116). I have some >>>> code to write a response, whose body is asynchronously generated. >>>> >>>> Here is how I got lost. In my code, ServletOutputStream.write() is >>>> called only if isReady() returns true. However, one of my test (server >>>> echoes back 1GB request which is also received using AsyncIO) failed for >>>> most of times due to IllegalStateException. Most likely it's because of >>>> "State=UNREADY"; very occasionally (I've only seen a few times), it would >>>> even fail with "State=READY", which makes me even more confused. The even >>>> trickier part is that if I ran another test before the failed test, it most >>>> likely would succeed... >>>> >>>> Can you enlighten me how what might be wrong?Any hint is appreciated. >>>> >>>> Thanks, >>>> Michael >>>> >>>> The code that does the write looks like this (_buffer is populated >>>> asynchrously, _os is ServletOutputStream): >>>> >>>> // To be called at onWritePossible() of WriteListener or when _buffer >>>> is populated asynchronously (i.e. previously we stopped write because >>>> _buffer is empty; _os.isReady() might still be true then) >>>> >>>> private void synchronized doWrite() throws IOException >>>> { >>>> _buffer.flip(); >>>> byte[] tmpBuf = new byte[4096]; >>>> while(_os.isReady() && _buffer.hasRemaining()) >>>> { >>>> int bytesNum = Math.min(tmpBuf.length, _buffer.remaining()); >>>> _buffer.get(tmpBuf, 0, bytesNum); >>>> // this is the only place we write to ServletOutputStream >>>> _os.write(tmpBuf, 0, bytesNum); >>>> } >>>> _buffer.compact(); >>>> } >>>> >>>> =========== Stack trace that failed with UNREADY state ========= >>>> >>>> 2015-04-13 14:30:05.665 HttpChannel [WARN] /echo >>>> java.lang.RuntimeException: >>>> at >>>> >>>> org.example.transport.http.server.AsyncIOResponseHandler.onError(AsyncIOResponseHandler.java:53) >>>> at org.eclipse.jetty.server.HttpOutput.run(HttpOutput.java:792) >>>> at >>>> org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1175) >>>> at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:365) >>>> at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:261) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) >>>> at java.lang.Thread.run(Thread.java:745) >>>> Caused by: java.lang.IllegalStateException: state=UNREADY >>>> at org.eclipse.jetty.server.HttpOutput.run(HttpOutput.java:822) >>>> ... 6 more >>>> >>>> 2015-04-13 14:30:05.665 SelectorManager [WARN] Could not process key >>>> for channel java.nio.channels.SocketChannel[connected local=/ >>>> 127.0.0.1:8099 remote=/127.0.0.1:58960] >>>> java.lang.IllegalStateException >>>> at >>>> org.eclipse.jetty.server.HttpOutput$AsyncICB.onCompleteSuccess(HttpOutput.java:858) >>>> at >>>> org.eclipse.jetty.server.HttpOutput$AsyncWrite.onCompleteSuccess(HttpOutput.java:988) >>>> at >>>> org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:300) >>>> at >>>> org.eclipse.jetty.util.IteratingCallback.succeeded(IteratingCallback.java:367) >>>> at >>>> org.eclipse.jetty.server.HttpConnection$SendCallback.onCompleteSuccess(HttpConnection.java:716) >>>> at >>>> org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:300 >>>> at >>>> org.eclipse.jetty.util.IteratingCallback.succeeded(IteratingCallback.java:367) >>>> at >>>> org.eclipse.jetty.io.WriteFlusher$PendingState.complete(WriteFlusher.java:270) >>>> at >>>> org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:383) >>>> at >>>> org.eclipse.jetty.io.SelectChannelEndPoint.onSelected(SelectChannelEndPoint.java:111) >>>> at >>>> org.eclipse.jetty.io.SelectorManager$ManagedSelector.processKey(SelectorManager.java:636 >>>> at >>>> org.eclipse.jetty.io.SelectorManager$ManagedSelector.select(SelectorManager.java:607) >>>> at >>>> org.eclipse.jetty.io.SelectorManager$ManagedSelector.run(SelectorManager.java:545) >>>> at >>>> org.eclipse.jetty.util.thread.NonBlockingThread.run(NonBlockingThread.java:52) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) >>>> at java.lang.Thread.run(Thread.java:745) >>>> >>>> >>>> =========== Stack trace that failed with UNREADY state ========= >>>> 2015-04-13 14:59:04.825 HttpChannel [WARN] /echo >>>> java.lang.RuntimeException: >>>> at >>>> org.example.transport.http.server.AsyncIOResponseHandler.onError(AsyncIOResponseHandler.java:53) >>>> at org.eclipse.jetty.server.HttpOutput.run(HttpOutput.java:792) >>>> at >>>> org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1175) >>>> at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:365) >>>> at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:261) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) >>>> at >>>> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) >>>> at java.lang.Thread.run(Thread.java:745) >>>> Caused by: java.lang.IllegalStateException: state=READY >>>> at org.eclipse.jetty.server.HttpOutput.run(HttpOutput.java:822) >>>> >>>> ... 6 more >>>> >>>> _______________________________________________ >>>> jetty-users mailing list >>>> [email protected] >>>> To change your delivery options, retrieve your password, or unsubscribe >>>> from this list, visit >>>> https://dev.eclipse.org/mailman/listinfo/jetty-users >>>> >>> >>> >>> _______________________________________________ >>> jetty-users mailing list >>> [email protected] >>> To change your delivery options, retrieve your password, or unsubscribe >>> from this list, visit >>> https://dev.eclipse.org/mailman/listinfo/jetty-users >>> >> >> >> _______________________________________________ >> jetty-users mailing list >> [email protected] >> To change your delivery options, retrieve your password, or unsubscribe >> from this list, visit >> https://dev.eclipse.org/mailman/listinfo/jetty-users >> > > > _______________________________________________ > jetty-users mailing list > [email protected] > To change your delivery options, retrieve your password, or unsubscribe > from this list, visit > https://dev.eclipse.org/mailman/listinfo/jetty-users >
_______________________________________________ jetty-users mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/jetty-users
