Fulfill the write promise of empty HTTP/2 DATA frames sooner
Motivation: DefaultHttp2ConnectionEncoder.FlowControlledData.write() does not complete the write promise of empty HTTP/2 DATA frames until either a non-DATA frame, a non-empty DATA frame or a DATA frame with endOfStream set. This makes the write promise of the empty DATA frame is notified much later than it could be. Modifications: - Notify the write promise of the empty DATA frames immediately is the queue contains empty DATA frames only Result: The write promise of an empty DATA frame is notified sooner.
This commit is contained in:
parent
acb40a87c3
commit
5b46cf25c1
|
@ -15,6 +15,7 @@
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -337,7 +338,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
|
||||||
private final CoalescingBufferQueue queue;
|
private final CoalescingBufferQueue queue;
|
||||||
private int dataSize;
|
private int dataSize;
|
||||||
|
|
||||||
public FlowControlledData(Http2Stream stream, ByteBuf buf, int padding, boolean endOfStream,
|
FlowControlledData(Http2Stream stream, ByteBuf buf, int padding, boolean endOfStream,
|
||||||
ChannelPromise promise) {
|
ChannelPromise promise) {
|
||||||
super(stream, padding, endOfStream, promise);
|
super(stream, padding, endOfStream, promise);
|
||||||
queue = new CoalescingBufferQueue(promise.channel());
|
queue = new CoalescingBufferQueue(promise.channel());
|
||||||
|
@ -361,11 +362,21 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
|
||||||
@Override
|
@Override
|
||||||
public void write(ChannelHandlerContext ctx, int allowedBytes) {
|
public void write(ChannelHandlerContext ctx, int allowedBytes) {
|
||||||
int queuedData = queue.readableBytes();
|
int queuedData = queue.readableBytes();
|
||||||
if (!endOfStream && (queuedData == 0 || allowedBytes == 0)) {
|
if (!endOfStream) {
|
||||||
// Nothing to write and we don't have to force a write because of EOS.
|
if (queuedData == 0) {
|
||||||
|
// There's no need to write any data frames because there are only empty data frames in the queue
|
||||||
|
// and it is not end of stream yet. Just complete their promises by writing an empty buffer.
|
||||||
|
ChannelPromise writePromise = ctx.newPromise().addListener(this);
|
||||||
|
queue.remove(0, writePromise).release();
|
||||||
|
ctx.write(Unpooled.EMPTY_BUFFER, writePromise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowedBytes == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine how much data to write.
|
// Determine how much data to write.
|
||||||
int writeableData = min(queuedData, allowedBytes);
|
int writeableData = min(queuedData, allowedBytes);
|
||||||
ChannelPromise writePromise = ctx.newPromise().addListener(this);
|
ChannelPromise writePromise = ctx.newPromise().addListener(this);
|
||||||
|
@ -408,7 +419,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
|
||||||
private final short weight;
|
private final short weight;
|
||||||
private final boolean exclusive;
|
private final boolean exclusive;
|
||||||
|
|
||||||
public FlowControlledHeaders(Http2Stream stream, Http2Headers headers, int streamDependency, short weight,
|
FlowControlledHeaders(Http2Stream stream, Http2Headers headers, int streamDependency, short weight,
|
||||||
boolean exclusive, int padding, boolean endOfStream, ChannelPromise promise) {
|
boolean exclusive, int padding, boolean endOfStream, ChannelPromise promise) {
|
||||||
super(stream, padding, endOfStream, promise);
|
super(stream, padding, endOfStream, promise);
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
|
@ -457,7 +468,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder {
|
||||||
protected boolean endOfStream;
|
protected boolean endOfStream;
|
||||||
protected int padding;
|
protected int padding;
|
||||||
|
|
||||||
public FlowControlledBase(final Http2Stream stream, int padding, boolean endOfStream,
|
protected FlowControlledBase(final Http2Stream stream, int padding, boolean endOfStream,
|
||||||
final ChannelPromise promise) {
|
final ChannelPromise promise) {
|
||||||
if (padding < 0) {
|
if (padding < 0) {
|
||||||
throw new IllegalArgumentException("padding must be >= 0");
|
throw new IllegalArgumentException("padding must be >= 0");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user