Fixes #3601 - HTTP2 stall on reset streams.

After review, introduced WriteFlusher.isPending() and now using that
in the test case to test for TCP congestion.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2019-08-07 11:48:31 +02:00
parent 762767c62c
commit 264ceb143d
2 changed files with 16 additions and 10 deletions

View File

@ -39,7 +39,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.AsyncContext; import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener; import javax.servlet.WriteListener;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
@ -941,7 +940,7 @@ public class StreamResetTest extends AbstractTest
start(new EmptyHttpServlet() start(new EmptyHttpServlet()
{ {
@Override @Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException
{ {
if (request.getPathInfo().equals("/1")) if (request.getPathInfo().equals("/1"))
service1(request, response); service1(request, response);
@ -1039,18 +1038,15 @@ public class StreamResetTest extends AbstractTest
Thread.sleep(1000); Thread.sleep(1000);
// Let the request write, it should not block. // Let the request write, it should not block.
requestLatch2.countDown(); requestLatch2.countDown();
assertTrue(writeLatch1.await(555, TimeUnit.SECONDS)); assertTrue(writeLatch1.await(5, TimeUnit.SECONDS));
} }
} }
private void waitUntilTCPCongested(WriteFlusher flusher) throws TimeoutException, InterruptedException private void waitUntilTCPCongested(WriteFlusher flusher) throws TimeoutException, InterruptedException
{ {
long start = System.nanoTime(); long start = System.nanoTime();
while (true) while (!flusher.isPending())
{ {
// Yuck! But no other easy way to detect this.
if ("P".equals(flusher.toStateString()))
break;
long elapsed = System.nanoTime() - start; long elapsed = System.nanoTime() - start;
if (TimeUnit.NANOSECONDS.toSeconds(elapsed) > 15) if (TimeUnit.NANOSECONDS.toSeconds(elapsed) > 15)
throw new TimeoutException(); throw new TimeoutException();

View File

@ -258,7 +258,7 @@ public abstract class WriteFlusher
*/ */
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
{ {
callback = Objects.requireNonNull(callback); Objects.requireNonNull(callback);
if (isFailed()) if (isFailed())
{ {
@ -523,12 +523,22 @@ public abstract class WriteFlusher
boolean isFailed() boolean isFailed()
{ {
return _state.get().getType() == StateType.FAILED; return isState(StateType.FAILED);
} }
boolean isIdle() boolean isIdle()
{ {
return _state.get().getType() == StateType.IDLE; return isState(StateType.IDLE);
}
public boolean isPending()
{
return isState(StateType.PENDING);
}
private boolean isState(StateType type)
{
return _state.get().getType() == type;
} }
public String toStateString() public String toStateString()