Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jetty-users] Question about behavior of WriteListener

I have a question about the usage/behavior of WriteListener because I encountered a strange problem: Writing works most of the time, but as soon as the data hit some magic size-limit it is truncated.

I created a very simplified class like this:

public class ByteArrayWriteListener implements WriteListener {
 
  private ServletOutputStream stream;
  private byte[] data;
  private AsyncContext asyncContext;
 
  public ByteArrayWriteListener(byte[] data, AsyncContext asyncContext, ServletOutputStream stream) {
    this.data = ""
    this.asyncContext = asyncContext;
    this.stream = stream;
  }
 
  @Override
  public void onError(Throwable t) {
  }
 
  @Override
  public void onWritePossible() throws IOException {
   stream.write(data);
   asyncContext.complete();
  }
 
}


all data is written as a big bunch and then the AsyncContext is immediately completed (note that it doesn't matter if complete is called outside the write-listener). This leads to the effect that the client simply gets only partial of the data when it grows up to a magic limit (maybe some response buffer size or so seem to depend on client load also...), setting the content-length prior to writing data has no effect. If I modify* the code that it checks (after the write) that the stream is ready then everything works.

Question: is it expected that a prior write is not completed if asyncContext is completed?

I can't find in the Javadoc any hint that AsyncContext.complete() might stop any already issued writes, and would expect that it throws an exception like calling stream.flush() for example if not isReady was called before.

Thanks in advance for any clarification :-)

* Modified code:
  @Override
  public void onWritePossible() throws IOException {
    if (!dataWritten) {
      stream.write(data);
      dataWritten = true;
    }
    if (stream.isReady()) {
      asyncContext.complete();
    }
  }


Back to the top