diff --git a/codec-classes-quic/src/main/java/io/netty/incubator/codec/quic/QuicheQuicStreamChannel.java b/codec-classes-quic/src/main/java/io/netty/incubator/codec/quic/QuicheQuicStreamChannel.java index c4351f25e..29446608d 100644 --- a/codec-classes-quic/src/main/java/io/netty/incubator/codec/quic/QuicheQuicStreamChannel.java +++ b/codec-classes-quic/src/main/java/io/netty/incubator/codec/quic/QuicheQuicStreamChannel.java @@ -601,6 +601,13 @@ public void beginRead() { readPending = true; if (readable) { ((QuicStreamChannelUnsafe) unsafe()).recv(); + + // As the stream was readable, and we called recv() ourselves we also need to call + // connectionSendAndFlush(). This is needed as recv() might consume data and so a window update + // frame might be produced. If we miss to call connectionSendAndFlush() we might never send the update + // to the remote peer and so the remote peer might never attempt to send more data. + // See also https://docs.rs/quiche/latest/quiche/struct.Connection.html#method.send. + parent().connectionSendAndFlush(); } } diff --git a/codec-native-quic/src/test/java/io/netty/incubator/codec/quic/QuicWritableTest.java b/codec-native-quic/src/test/java/io/netty/incubator/codec/quic/QuicWritableTest.java index 553ccf7ec..db3f08933 100644 --- a/codec-native-quic/src/test/java/io/netty/incubator/codec/quic/QuicWritableTest.java +++ b/codec-native-quic/src/test/java/io/netty/incubator/codec/quic/QuicWritableTest.java @@ -23,7 +23,6 @@ import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.PromiseNotifier; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -41,14 +40,12 @@ public class QuicWritableTest extends AbstractQuicTest { - @Disabled("Flaky, needs investigation") @ParameterizedTest @MethodSource("newSslTaskExecutors") public void testCorrectlyHandleWritabilityReadRequestedInReadComplete(Executor executor) throws Throwable { testCorrectlyHandleWritability(executor, true); } - @Disabled("Flaky, needs investigation") @ParameterizedTest @MethodSource("newSslTaskExecutors") public void testCorrectlyHandleWritabilityReadRequestedInRead(Executor executor) throws Throwable {