457032 - Request sent from a failed CompleteListener due to connect timeout is failed immediately.
Fixed by copying the exchange queue and failing only the exchanges that are present in the copy.
This commit is contained in:
parent
9618f45ead
commit
51aafc78a4
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.client;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.AsynchronousCloseException;
|
import java.nio.channels.AsynchronousCloseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
@ -233,9 +234,11 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
||||||
*/
|
*/
|
||||||
public void abort(Throwable cause)
|
public void abort(Throwable cause)
|
||||||
{
|
{
|
||||||
HttpExchange exchange;
|
// Copy the queue of exchanges and fail only those that are queued at this moment.
|
||||||
// Just peek(), the abort() will remove it from the queue.
|
// The application may queue another request from the failure/complete listener
|
||||||
while ((exchange = exchanges.peek()) != null)
|
// and we don't want to fail it immediately as if it was queued before the failure.
|
||||||
|
// The call to Request.abort() will remove the exchange from the exchanges queue.
|
||||||
|
for (HttpExchange exchange : new ArrayList<>(exchanges))
|
||||||
exchange.getRequest().abort(cause);
|
exchange.getRequest().abort(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -57,7 +56,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
|
@ -301,7 +299,6 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Slow
|
@Slow
|
||||||
@Test
|
@Test
|
||||||
public void testConnectTimeoutFailsRequest() throws Exception
|
public void testConnectTimeoutFailsRequest() throws Exception
|
||||||
|
@ -333,10 +330,9 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Assert.assertNotNull(request.getAbortCause());
|
Assert.assertNotNull(request.getAbortCause());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Slow
|
@Slow
|
||||||
@Test
|
@Test
|
||||||
public void testConnectTimeoutIsCancelledByShorterTimeout() throws Exception
|
public void testConnectTimeoutIsCancelledByShorterRequestTimeout() throws Exception
|
||||||
{
|
{
|
||||||
String host = "10.255.255.1";
|
String host = "10.255.255.1";
|
||||||
int port = 80;
|
int port = 80;
|
||||||
|
@ -368,6 +364,49 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
||||||
Assert.assertNotNull(request.getAbortCause());
|
Assert.assertNotNull(request.getAbortCause());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void retryAfterConnectTimeout() throws Exception
|
||||||
|
{
|
||||||
|
final String host = "10.255.255.1";
|
||||||
|
final int port = 80;
|
||||||
|
int connectTimeout = 1000;
|
||||||
|
assumeConnectTimeout(host, port, connectTimeout);
|
||||||
|
|
||||||
|
start(new EmptyServerHandler());
|
||||||
|
client.stop();
|
||||||
|
client.setConnectTimeout(connectTimeout);
|
||||||
|
client.start();
|
||||||
|
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
Request request = client.newRequest(host, port);
|
||||||
|
request.scheme(scheme)
|
||||||
|
.send(new Response.CompleteListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onComplete(Result result)
|
||||||
|
{
|
||||||
|
if (result.isFailed())
|
||||||
|
{
|
||||||
|
// Retry
|
||||||
|
client.newRequest(host, port)
|
||||||
|
.scheme(scheme)
|
||||||
|
.send(new Response.CompleteListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onComplete(Result result)
|
||||||
|
{
|
||||||
|
if (result.isFailed())
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertTrue(latch.await(333 * connectTimeout, TimeUnit.MILLISECONDS));
|
||||||
|
Assert.assertNotNull(request.getAbortCause());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVeryShortTimeout() throws Exception
|
public void testVeryShortTimeout() throws Exception
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue