-
Bug
-
Resolution: Done
-
Blocker
-
1.1.3.Final, 1.2.0.Beta10
When the connection is suddenly terminated during the period we access the asynchronous servlet application, the connection will be leaked. However, the connection won't be leak when we access the synchronous servlet application.
Some of the stacktrace are as follows:
14:34:23,751 ERROR [io.undertow.request] (default task-22) Blocking request fail
at io.undertow.servlet.spec.HttpServletResponseImpl.responseDone(HttpSer
at io.undertow.servlet.spec.AsyncContextImpl$3.run(AsyncContextImpl.java
at io.undertow.servlet.spec.AsyncContextImpl$6.run(AsyncContextImpl.java
at io.undertow.servlet.spec.AsyncContextImpl$TaskDispatchRunnable.run(As
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
Caused by: java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.write0(Native Method) [rt.jar:1.7.0_25]
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) [rt.jar:1
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:94) [rt.jar:1.7.0
at sun.nio.ch.IOUtil.write(IOUtil.java:51) [rt.jar:1.7.0_25]
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:466) [rt.ja
at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:150)
at io.undertow.server.protocol.http.HttpResponseConduit.processWrite(Htt
at io.undertow.server.protocol.http.HttpResponseConduit.flush(HttpRespon
at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.flush(Abstr
at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkCha
at io.undertow.channels.DetachableStreamSinkChannel.flush(DetachableStre
at org.xnio.channels.Channels.flushBlocking(Channels.java:63)
at io.undertow.servlet.spec.ServletOutputStreamImpl.close(ServletOutputS
at io.undertow.servlet.spec.HttpServletResponseImpl.closeStreamAndWriter
at io.undertow.servlet.spec.HttpServletResponseImpl.responseDone(HttpSer
... 6 more
Here's the test war code you can used to reproduce this phenomenon:
import java.io.IOException; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns="/asyncDemoServlet",asyncSupported=true) public class AsyncDemoServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); //Execute the business logic in sub-thread. AsyncContext ctx = request.startAsync(); new Thread(new Executor(ctx)).start(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public class Executor implements Runnable { private AsyncContext ctx = null; public Executor(AsyncContext ctx){ this.ctx = ctx; } public void run(){ try { ctx.getResponse().getOutputStream().write("aaa".getBytes()); //wait for 5 seconds to simulate the business logic. Thread.sleep(5000); ctx.getResponse().getOutputStream().flush(); ctx.complete(); } catch (Exception e) { e.printStackTrace(); } } } }