Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Async IO failed with IllegalStateException in HttpOutput

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 <joakim@xxxxxxxxxxx> 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 <joakim@xxxxxxxxxxx>
Expert advice, services and support from from the Jetty & CometD experts

On Tue, Apr 14, 2015 at 1:54 PM, Michael Aaron <maaaroooon@xxxxxxxxx> 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 <joakim@xxxxxxxxxxx> 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.



--
Joakim Erdfelt <joakim@xxxxxxxxxxx>
Expert advice, services and support from from the Jetty & CometD experts

On Mon, Apr 13, 2015 at 4:00 PM, Michael Aaron <maaaroooon@xxxxxxxxx> 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
jetty-users@xxxxxxxxxxx
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
jetty-users@xxxxxxxxxxx
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
jetty-users@xxxxxxxxxxx
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
jetty-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users


Back to the top