1 /* 2 * Copyright 2015 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, version 2.0 (the 5 * "License"); you may not use this file except in compliance with the License. You may obtain a 6 * copy of the License at: 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software distributed under the License 11 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 * or implied. See the License for the specific language governing permissions and limitations under 13 * the License. 14 */ 15 16 package io.netty5.handler.codec.http2; 17 18 import io.netty5.util.internal.UnstableApi; 19 20 /** 21 * An object (used by remote flow control) that is responsible for distributing the bytes to be 22 * written across the streams in the connection. 23 */ 24 @UnstableApi 25 public interface StreamByteDistributor { 26 27 /** 28 * State information for the stream, indicating the number of bytes that are currently 29 * streamable. This is provided to the {@link #updateStreamableBytes(StreamState)} method. 30 */ 31 interface StreamState { 32 /** 33 * Gets the stream this state is associated with. 34 */ 35 Http2Stream stream(); 36 37 /** 38 * Get the amount of bytes this stream has pending to send. The actual amount written must not exceed 39 * {@link #windowSize()}! 40 * @return The amount of bytes this stream has pending to send. 41 * @see Http2CodecUtil#streamableBytes(StreamState) 42 */ 43 long pendingBytes(); 44 45 /** 46 * Indicates whether or not there are frames pending for this stream. 47 */ 48 boolean hasFrame(); 49 50 /** 51 * The size (in bytes) of the stream's flow control window. The amount written must not exceed this amount! 52 * <p>A {@link StreamByteDistributor} needs to know the stream's window size in order to avoid allocating bytes 53 * if the window size is negative. The window size being {@code 0} may also be significant to determine when if 54 * an stream has been given a chance to write an empty frame, and also enables optimizations like not writing 55 * empty frames in some situations (don't write headers until data can also be written). 56 * @return the size of the stream's flow control window. 57 * @see Http2CodecUtil#streamableBytes(StreamState) 58 */ 59 int windowSize(); 60 } 61 62 /** 63 * Object that performs the writing of the bytes that have been allocated for a stream. 64 */ 65 interface Writer { 66 /** 67 * Writes the allocated bytes for this stream. 68 * <p> 69 * Any {@link Throwable} thrown from this method is considered a programming error. 70 * A {@code GOAWAY} frame will be sent and the will be connection closed. 71 * @param stream the stream for which to perform the write. 72 * @param numBytes the number of bytes to write. 73 */ 74 void write(Http2Stream stream, int numBytes); 75 } 76 77 /** 78 * Called when the streamable bytes for a stream has changed. Until this 79 * method is called for the first time for a give stream, the stream is assumed to have no 80 * streamable bytes. 81 */ 82 void updateStreamableBytes(StreamState state); 83 84 /** 85 * Explicitly update the dependency tree. This method is called independently of stream state changes. 86 * @param childStreamId The stream identifier associated with the child stream. 87 * @param parentStreamId The stream identifier associated with the parent stream. May be {@code 0}, 88 * to make {@code childStreamId} and immediate child of the connection. 89 * @param weight The weight which is used relative to other child streams for {@code parentStreamId}. This value 90 * must be between 1 and 256 (inclusive). 91 * @param exclusive If {@code childStreamId} should be the exclusive dependency of {@code parentStreamId}. 92 */ 93 void updateDependencyTree(int childStreamId, int parentStreamId, short weight, boolean exclusive); 94 95 /** 96 * Distributes up to {@code maxBytes} to those streams containing streamable bytes and 97 * iterates across those streams to write the appropriate bytes. Criteria for 98 * traversing streams is undefined and it is up to the implementation to determine when to stop 99 * at a given stream. 100 * 101 * <p>The streamable bytes are not automatically updated by calling this method. It is up to the 102 * caller to indicate the number of bytes streamable after the write by calling 103 * {@link #updateStreamableBytes(StreamState)}. 104 * 105 * @param maxBytes the maximum number of bytes to write. 106 * @return {@code true} if there are still streamable bytes that have not yet been written, 107 * otherwise {@code false}. 108 * @throws Http2Exception If an internal exception occurs and internal connection state would otherwise be 109 * corrupted. 110 */ 111 boolean distribute(int maxBytes, Writer writer) throws Http2Exception; 112 }