WriteListener.onWritePossible is never called back again if the origin cuts the socket
Tomcat 8.5.55 (also tried with 8.5.37).
Similar to “Bug 62614 - Async servlet over HTTP/2 WriteListener does not work because onWritePossible is never called back again” but using NIO connector:
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" />
I’m unable to create an example that reproduces this issue. So I will explain what’s happening and I hope someone can give me some clue about what’s going on.
The case is simple: we connect to our servlet using http components setting a response timeout of 10 seconds. Since our servlet takes less than 5 seconds to get the response from the backend, it returns all the content to the client (it’s about 180K).
The point is when we set a response timeout of, for instance, 2 seconds. In this case the client closes the socket with the servlet before it can return the response. In fact, in most situations, when we set the WriteListener to the async response this socket is already closed. In this situation 2 different things are randomly happening:
1. The expected, the WriteListener throws an IOException: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe, and the ‘onError’ method is called:
2. The unexpected. The ‘onWritePossible’ method is called just once.
In this case ‘onWritePossible’ is called, this.os.isReady is true and the execution enter into the cycle but the above ‘this.os.write’ does not throw any exception, then ‘this.os.isReady’ becomes false so the execution exits the cycle and the ‘onWritePossible’ method terminates. And it’s never called again (neither the ‘onError’ method).
Here I leave a link to the interesting part of the WriteListener code and the 3 traces: the right one returning the document (trace_OK.txt), the right one returning the error (trace_OK_with_broken_pipe.txt) and the wrong one calling ‘onWritePossible’ just once (trace_KO.txt) : https://github.com/joanbalaguero/Tomcat.git
I tried to search a solution for this, no success. I developed a simple test case, and it was impossible to reproduce the issue. I’m pretty sure it’s a lack of knowledge about how this listener works in this case (sockets already closed) but after reading tutorials and more tutorials I’m not able to find the solution.
So any help would be very very appreciated.
Thanks for your time.
To unsubscribe, e-mail: [hidden email] For additional commands, e-mail: [hidden email]