Merge branch 'jetty-9.3.x' of github.com:eclipse/jetty.project into jetty-9.3.x

This commit is contained in:
Greg Wilkins 2018-08-28 10:53:20 +10:00
commit 05d4049d46
2 changed files with 49 additions and 10 deletions

View File

@ -210,16 +210,7 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
if (getHttpExchanges().isEmpty())
{
if (getHttpClient().isRemoveIdleDestinations() && connectionPool.isEmpty())
{
// There is a race condition between this thread removing the destination
// and another thread queueing a request to this same destination.
// If this destination is removed, but the request queued, a new connection
// will be opened, the exchange will be executed and eventually the connection
// will idle timeout and be closed. Meanwhile a new destination will be created
// in HttpClient and will be used for other requests.
getHttpClient().removeDestination(this);
}
tryRemoveIdleDestination();
}
else
{
@ -237,6 +228,27 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
connectionPool.close();
}
public void abort(Throwable cause)
{
super.abort(cause);
if (getHttpExchanges().isEmpty())
tryRemoveIdleDestination();
}
private void tryRemoveIdleDestination()
{
if (getHttpClient().isRemoveIdleDestinations() && connectionPool.isEmpty())
{
// There is a race condition between this thread removing the destination
// and another thread queueing a request to this same destination.
// If this destination is removed, but the request queued, a new connection
// will be opened, the exchange will be executed and eventually the connection
// will idle timeout and be closed. Meanwhile a new destination will be created
// in HttpClient and will be used for other requests.
getHttpClient().removeDestination(this);
}
}
@Override
public String toString()
{

View File

@ -280,6 +280,33 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest
Assert.assertNotSame(destinationBefore, destinationAfter);
}
@Test
public void testDestinationIsRemovedAfterConnectionError() throws Exception
{
String host = "localhost";
int port = connector.getLocalPort();
client.setRemoveIdleDestinations(true);
Assert.assertTrue("Destinations of a fresh client must be empty", client.getDestinations().isEmpty());
server.stop();
Request request = client.newRequest(host, port).scheme(this.scheme);
try
{
request.send();
Assert.fail("Request to a closed port must fail");
}
catch (Exception expected)
{
}
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(1);
while (!client.getDestinations().isEmpty() && System.nanoTime() < deadline)
{
Thread.sleep(10);
}
Assert.assertTrue("Destination must be removed after connection error", client.getDestinations().isEmpty());
}
private Connection timedPoll(Queue<Connection> connections, long time, TimeUnit unit) throws InterruptedException
{
long start = System.nanoTime();