Flow control needs improvements.

This commit is contained in:
Simone Bordet 2014-08-05 00:28:06 +02:00
parent 20925ded97
commit ac7aa4decc
1 changed files with 25 additions and 18 deletions

View File

@ -640,6 +640,10 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
{ {
synchronized (queue) synchronized (queue)
{ {
// The session window size may vary concurrently upon receipt of
// WINDOW_UPDATE or SETTINGS so we read it here and not in the loop.
// The stream window size is read in the loop, but it's always
// capped by the session window size.
int sessionWindow = getWindowSize(); int sessionWindow = getWindowSize();
int nonStalledIndex = 0; int nonStalledIndex = 0;
int size = queue.size(); int size = queue.size();
@ -663,22 +667,21 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
continue; continue;
} }
if (stream != null) // The stream may have a smaller window than the session.
Integer streamWindow = streams.get(stream);
if (streamWindow == null)
{ {
Integer streamWindow = streams.get(stream); streamWindow = stream.getWindowSize();
if (streamWindow == null) streams.put(stream, streamWindow);
{ }
streamWindow = stream.getWindowSize();
streams.put(stream, streamWindow);
}
// Is it a frame belonging to an already stalled stream ? // Is it a frame belonging to an already stalled stream ?
if (streamWindow <= 0) if (streamWindow <= 0)
{ {
flowControl.onStreamStalled(stream); flowControl.onStreamStalled(stream);
++nonStalledIndex; ++nonStalledIndex;
continue; // There may be *non* flow controlled frames to send.
} continue;
} }
} }
} }
@ -888,12 +891,16 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
public void generate(ByteBufferPool.Lease lease) public void generate(ByteBufferPool.Lease lease)
{ {
DataFrame dataFrame = (DataFrame)frame; DataFrame dataFrame = (DataFrame)frame;
int windowSize = stream.getWindowSize(); int flowControlLength = dataFrame.remaining() + dataFrame.padding();
int frameLength = dataFrame.remaining();
this.length = Math.min(frameLength, windowSize); int streamWindowSize = stream.getWindowSize();
generator.data(lease, dataFrame, length); int sessionWindowSize = getWindowSize();
int windowSize = Math.min(streamWindowSize, sessionWindowSize);
length = Math.min(flowControlLength, windowSize);
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Generated {}, maxLength={}", dataFrame, length); LOG.debug("Generated {}, maxLength={}", dataFrame, length);
generator.data(lease, dataFrame, length);
} }
@Override @Override