-
Bug
-
Resolution: Done
-
Major
-
2.0.17.Final, 1.4.18.SP11
-
None
This two lines can throw exceptions in RequestLimit:
task.exchange.addExchangeCompleteListener(COMPLETION_LISTENER);
task.exchange.dispatch(task.next);
There is a finally for calling the next listener, however decrementRequests() isn't in it. In case of an error the currently polled exchange will be skipped while decrementRequests() is also not called: oops, we lost a thread! At a larger workload we lose all the threads, sooner or later. We solved the problem with the change contained by this pull request.
The most common exception we experienced is this (this stack is from 1.4.18, but the problem still exists with 2.x):
java.lang.IllegalStateException: UT000139: Exchange already complete
at io.undertow.server.HttpServerExchange.addExchangeCompleteListener(HttpServerExchange.java:923)
at io.undertow.server.handlers.RequestLimit$2.exchangeEvent(RequestLimit.java:92)
at io.undertow.server.HttpServerExchange$ExchangeCompleteNextListener.proceed(HttpServerExchange.java:1845)
at io.undertow.server.handlers.proxy.ProxyHandler$2.exchangeEvent(ProxyHandler.java:196)
at io.undertow.server.HttpServerExchange$ExchangeCompleteNextListener.proceed(HttpServerExchange.java:1845)
at io.undertow.server.handlers.proxy.ProxyConnectionPool$3.exchangeEvent(ProxyConnectionPool.java:332)
at io.undertow.server.HttpServerExchange.invokeExchangeCompleteListeners(HttpServerExchange.java:1258)
at io.undertow.server.HttpServerExchange.terminateResponse(HttpServerExchange.java:1538)
at io.undertow.server.Connectors.terminateResponse(Connectors.java:143)
at io.undertow.server.protocol.http.ServerFixedLengthStreamSinkConduit.channelFinished(ServerFixedLengthStreamSinkConduit.java:56)
at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.exitFlush(AbstractFixedLengthStreamSinkConduit.java:316)
at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.flush(AbstractFixedLengthStreamSinkConduit.java:234)
at org.xnio.conduits.AbstractSinkConduit.flush(AbstractSinkConduit.java:86)
at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkChannel.java:162)
at io.undertow.channels.DetachableStreamSinkChannel.flush(DetachableStreamSinkChannel.java:119)
at io.undertow.io.AsyncSenderImpl.close(AsyncSenderImpl.java:338)
at io.undertow.io.DefaultIoCallback.onComplete(DefaultIoCallback.java:54)
at io.undertow.io.AsyncSenderImpl.invokeOnComplete(AsyncSenderImpl.java:396)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:233)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:310)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:282)
at io.undertow.io.AsyncSenderImpl.send(AsyncSenderImpl.java:316)
...