484585 - Avoid sending request using a connection that is idle timing out.

Rewritten handling of idle timeouts in light of issue #484718.
This commit is contained in:
Simone Bordet 2015-12-21 11:46:40 +01:00
parent 35c4c24099
commit 8f4cc73613
7 changed files with 23 additions and 36 deletions

View File

@ -220,13 +220,9 @@ public abstract class HttpConnection implements Connection
{
if (LOG.isDebugEnabled())
LOG.debug("Idle timeout state {} - {}", idleTimeoutState, this);
if (idleTimeoutState.compareAndSet(0, -1))
close(new TimeoutException("idle_timeout"));
return false;
return idleTimeoutState.compareAndSet(0, -1);
}
protected abstract void close(Throwable failure);
@Override
public String toString()
{

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.client.http;
import java.nio.channels.AsynchronousCloseException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@ -95,12 +96,12 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
}
@Override
protected boolean onReadTimeout()
public boolean onIdleExpired()
{
boolean close = delegate.onIdleTimeout();
if (!close && !isClosed())
fillInterested();
return close;
if (close)
close(new TimeoutException("Idle timeout " + getEndPoint().getIdleTimeout() + "ms"));
return false;
}
@Override
@ -206,12 +207,6 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
HttpConnectionOverHTTP.this.close();
}
@Override
protected void close(Throwable failure)
{
HttpConnectionOverHTTP.this.close(failure);
}
@Override
public String toString()
{

View File

@ -169,7 +169,7 @@ public class HttpReceiverOverHTTPTest
FutureResponseListener listener = (FutureResponseListener)exchange.getResponseListeners().get(0);
connection.getHttpChannel().receive();
// Simulate an idle timeout
connection.onReadTimeout();
connection.onIdleExpired();
try
{

View File

@ -24,6 +24,7 @@ import java.nio.channels.AsynchronousCloseException;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.client.HttpClient;
@ -190,12 +191,14 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
}
@Override
protected boolean onReadTimeout()
public boolean onIdleExpired()
{
boolean close = delegate.onIdleTimeout();
if (!close && !isClosed())
fillInterested();
return close;
if (multiplexed)
close &= isFillInterested();
if (close)
close(new TimeoutException("Idle timeout " + getEndPoint().getIdleTimeout() + "ms"));
return false;
}
protected void release(HttpChannelOverFCGI channel)
@ -324,7 +327,6 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
HttpConnectionOverFCGI.this.close();
}
@Override
protected void close(Throwable failure)
{
HttpConnectionOverFCGI.this.close(failure);

View File

@ -113,12 +113,12 @@ public class HTTP2Connection extends AbstractConnection
}
@Override
protected boolean onReadTimeout()
public boolean onIdleExpired()
{
if (LOG.isDebugEnabled())
LOG.debug("Idle timeout {}ms expired on {}", getEndPoint().getIdleTimeout(), this);
if (!session.onIdleTimeout())
fillInterested();
boolean close = session.onIdleTimeout();
boolean idle = isFillInterested();
if (close && idle)
session.close(ErrorCode.NO_ERROR.code, "idle_timeout", Callback.NOOP);
return false;
}

View File

@ -832,7 +832,7 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
* stuck because of TCP congestion), therefore we terminate.
* See {@link #onGoAway(GoAwayFrame)}.
*
* @return true if the session has been closed, false otherwise
* @return true if the session should be closed, false otherwise
* @see #onGoAway(GoAwayFrame)
* @see #close(int, String, Callback)
* @see #onShutdown()
@ -844,22 +844,17 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
{
case NOT_CLOSED:
{
if (notifyIdleTimeout(this))
{
close(ErrorCode.NO_ERROR.code, "idle_timeout", Callback.NOOP);
return true;
}
return false;
return notifyIdleTimeout(this);
}
case LOCALLY_CLOSED:
case REMOTELY_CLOSED:
{
abort(new TimeoutException());
return true;
return false;
}
default:
{
return true;
return false;
}
}
}

View File

@ -76,7 +76,6 @@ public class HttpConnectionOverHTTP2 extends HttpConnection
close(new AsynchronousCloseException());
}
@Override
protected void close(Throwable failure)
{
// First close then abort, to be sure that the connection cannot be reused