Thank you very much, Simone and Greg, you completely clarified this part for me.
Now I'm stuck with a different problem.
I have a queue of output data chunks that is being filled out by a completely
separate thread, not related to the servlet container.
After adding some data, this thread calls flush() to send all collected data to the client.
In the beginning data queue is empty, so onWritePossible that was called when we first
register ReadListener, exists.
When separate thread calls flush(), we need to notify Jetty somehow, that it needs to start calling onWritePossible again.
(in NIO terms - "register interest in writing").
How can we do that?
Thank you very much,
Richard
Simplified code:
--------------------
public class AsyncIOExample2 extends HttpServlet {
private Queue outputContentQueue = new ConcurrentLinkedQueue();
protected void doGet(HttpServletRequest
request, HttpServletResponse response) throws ServletException, IOException {
// Prepare the async output
AsyncContext async = request.startAsync();
ServletOutputStream out = response.getOutputStream();
out.setWriteListener(new StandardDataStream(async, out));
}
// called by a separate thread to collect data until flush() is called
public void write(byte[] dataBytes) throws IOException
{
outputContentQueue.add(dataBytes);
}
// called by a separate thread, which should not block in this method
public void flush() throws IOException
{
// What is the correct way to communicate to the servlet container
// that it should now write all the data collected in contentQueue.
// I.e. we want Jetty to start calling onWritePossible()
}
private class StandardDataStream implements WriteListener
{
private AsyncContext async;
private ServletOutputStream out;
private StandardDataStream(AsyncContext async, ServletOutputStream out)
{
this.async = async;
this.out =
out;
}
public void onWritePossible() throws IOException
{
while (out.isReady()) {
byte[] dataBytes = (byte[]) outputContentQueue.poll();
if (dataBytes == null) {
break;
}
out.write(dataBytes);
}
}
public void onError(Throwable t)
{
getServletContext().log("Async Error",t);
async.complete();
}
}
}