Fixes #1046 - Improve HTTP2Flusher error report.
Now remembering the cause of the termination, and propagating it to other components.
This commit is contained in:
parent
8cefaba2a4
commit
8fef113372
|
@ -19,7 +19,6 @@
|
|||
package org.eclipse.jetty.http2;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -47,7 +46,7 @@ public class HTTP2Flusher extends IteratingCallback
|
|||
private final List<Entry> actives = new ArrayList<>();
|
||||
private final HTTP2Session session;
|
||||
private final ByteBufferPool.Lease lease;
|
||||
private boolean terminated;
|
||||
private Throwable terminated;
|
||||
|
||||
public HTTP2Flusher(HTTP2Session session)
|
||||
{
|
||||
|
@ -57,52 +56,54 @@ public class HTTP2Flusher extends IteratingCallback
|
|||
|
||||
public void window(IStream stream, WindowUpdateFrame frame)
|
||||
{
|
||||
boolean closed;
|
||||
Throwable closed;
|
||||
synchronized (this)
|
||||
{
|
||||
closed = terminated;
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
windows.offer(new WindowEntry(stream, frame));
|
||||
}
|
||||
// Flush stalled data.
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
iterate();
|
||||
}
|
||||
|
||||
public boolean prepend(Entry entry)
|
||||
{
|
||||
boolean closed;
|
||||
Throwable closed;
|
||||
synchronized (this)
|
||||
{
|
||||
closed = terminated;
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
{
|
||||
frames.add(0, entry);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Prepended {}, frames={}", entry, frames.size());
|
||||
}
|
||||
}
|
||||
if (closed)
|
||||
closed(entry, new ClosedChannelException());
|
||||
return !closed;
|
||||
if (closed == null)
|
||||
return true;
|
||||
closed(entry, closed);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean append(Entry entry)
|
||||
{
|
||||
boolean closed;
|
||||
Throwable closed;
|
||||
synchronized (this)
|
||||
{
|
||||
closed = terminated;
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
{
|
||||
frames.add(entry);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Appended {}, frames={}", entry, frames.size());
|
||||
}
|
||||
}
|
||||
if (closed)
|
||||
closed(entry, new ClosedChannelException());
|
||||
return !closed;
|
||||
if (closed == null)
|
||||
return true;
|
||||
closed(entry, closed);
|
||||
return false;
|
||||
}
|
||||
|
||||
private Entry remove(int index)
|
||||
|
@ -122,15 +123,15 @@ public class HTTP2Flusher extends IteratingCallback
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Action process() throws Exception
|
||||
protected Action process() throws Throwable
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Flushing {}", session);
|
||||
|
||||
synchronized (this)
|
||||
{
|
||||
if (terminated)
|
||||
throw new ClosedChannelException();
|
||||
if (terminated != null)
|
||||
throw terminated;
|
||||
|
||||
// First thing, update the window sizes, so we can
|
||||
// reason about the frames to remove from the queue.
|
||||
|
@ -269,13 +270,13 @@ public class HTTP2Flusher extends IteratingCallback
|
|||
{
|
||||
lease.recycle();
|
||||
|
||||
boolean closed;
|
||||
Throwable closed;
|
||||
synchronized (this)
|
||||
{
|
||||
closed = terminated;
|
||||
terminated = true;
|
||||
terminated = x;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{}, active/queued={}/{}", closed ? "Closing" : "Failing", actives.size(), frames.size());
|
||||
LOG.debug("{}, active/queued={}/{}", closed != null ? "Closing" : "Failing", actives.size(), frames.size());
|
||||
actives.addAll(frames);
|
||||
frames.clear();
|
||||
}
|
||||
|
@ -285,21 +286,21 @@ public class HTTP2Flusher extends IteratingCallback
|
|||
|
||||
// If the failure came from within the
|
||||
// flusher, we need to close the connection.
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
session.abort(x);
|
||||
}
|
||||
|
||||
void terminate()
|
||||
void terminate(Throwable cause)
|
||||
{
|
||||
boolean closed;
|
||||
Throwable closed;
|
||||
synchronized (this)
|
||||
{
|
||||
closed = terminated;
|
||||
terminated = true;
|
||||
terminated = cause;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{}", closed ? "Terminated" : "Terminating");
|
||||
LOG.debug("{}", closed != null ? "Terminated" : "Terminating");
|
||||
}
|
||||
if (!closed)
|
||||
if (closed == null)
|
||||
iterate();
|
||||
}
|
||||
|
||||
|
|
|
@ -959,7 +959,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
endPoint.close();
|
||||
}
|
||||
|
||||
private void terminate()
|
||||
private void terminate(Throwable cause)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
@ -972,7 +972,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
{
|
||||
if (closed.compareAndSet(current, CloseState.CLOSED))
|
||||
{
|
||||
flusher.terminate();
|
||||
flusher.terminate(cause);
|
||||
for (IStream stream : streams.values())
|
||||
stream.close();
|
||||
streams.clear();
|
||||
|
@ -992,7 +992,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
protected void abort(Throwable failure)
|
||||
{
|
||||
notifyFailure(this, failure);
|
||||
terminate();
|
||||
terminate(failure);
|
||||
}
|
||||
|
||||
public boolean isDisconnected()
|
||||
|
@ -1209,7 +1209,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
}
|
||||
case DISCONNECT:
|
||||
{
|
||||
terminate();
|
||||
terminate(new ClosedChannelException());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue