private void updateSendWindowSize()

in src/main/java/com/twitter/http2/HttpConnectionHandler.java [1001:1062]


    private void updateSendWindowSize(
            ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) {
        httpConnection.updateSendWindowSize(streamId, windowSizeIncrement);

        while (true) {
            // Check if we have unblocked a stalled stream
            HttpConnection.PendingWrite e = httpConnection.getPendingWrite(streamId);
            if (e == null) {
                break;
            }

            HttpDataFrame httpDataFrame = e.httpDataFrame;
            int dataFrameSize = httpDataFrame.content().readableBytes();
            int writeStreamId = httpDataFrame.getStreamId();
            int sendWindowSize = httpConnection.getSendWindowSize(writeStreamId);
            int connectionSendWindowSize = httpConnection.getSendWindowSize(
                    HTTP_CONNECTION_STREAM_ID);
            sendWindowSize = Math.min(sendWindowSize, connectionSendWindowSize);

            if (sendWindowSize <= 0) {
                return;
            } else if (sendWindowSize < dataFrameSize) {
                // We can send a partial frame
                httpConnection.updateSendWindowSize(writeStreamId, -1 * sendWindowSize);
                httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * sendWindowSize);

                // Create a partial data frame whose length is the current window size
                ByteBuf data = httpDataFrame.content().readSlice(sendWindowSize).retain();
                ByteBuf partialDataFrame = httpFrameEncoder.encodeDataFrame(writeStreamId, false, data);

                ChannelPromise writeFuture = ctx.channel().newPromise();

                // The transfer window size is pre-decremented when sending a data frame downstream.
                // Close the connection on write failures that leaves the transfer window in a corrupt state.
                writeFuture.addListener(connectionErrorListener);

                ctx.writeAndFlush(partialDataFrame, writeFuture);
            } else {
                // Window size is large enough to send entire data frame
                httpConnection.removePendingWrite(writeStreamId);
                httpConnection.updateSendWindowSize(writeStreamId, -1 * dataFrameSize);
                httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * dataFrameSize);

                // The transfer window size is pre-decremented when sending a data frame downstream.
                // Close the connection on write failures that leaves the transfer window in a corrupt state.
                e.promise.addListener(connectionErrorListener);

                // Close the local side of the stream if this is the last frame
                if (httpDataFrame.isLast()) {
                    halfCloseStream(writeStreamId, false, e.promise);
                }

                ByteBuf frame = httpFrameEncoder.encodeDataFrame(
                        writeStreamId,
                        httpDataFrame.isLast(),
                        httpDataFrame.content()
                );

                ctx.writeAndFlush(frame, e.promise);
            }
        }
    }