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

Reply via email to