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.netty.handler.codec.http2;
17
18 /**
19 * An object (used by remote flow control) that is responsible for distributing the bytes to be
20 * written across the streams in the connection.
21 */
22 public interface StreamByteDistributor {
23
24 /**
25 * State information for the stream, indicating the number of bytes that are currently
26 * streamable. This is provided to the {@link #updateStreamableBytes(StreamState)} method.
27 */
28 interface StreamState {
29 /**
30 * Gets the stream this state is associated with.
31 */
32 Http2Stream stream();
33
34 /**
35 * Get the amount of bytes this stream has pending to send. The actual amount written must not exceed
36 * {@link #windowSize()}!
37 * @return The amount of bytes this stream has pending to send.
38 * @see Http2CodecUtil#streamableBytes(StreamState)
39 */
40 long pendingBytes();
41
42 /**
43 * Indicates whether or not there are frames pending for this stream.
44 */
45 boolean hasFrame();
46
47 /**
48 * The size (in bytes) of the stream's flow control window. The amount written must not exceed this amount!
49 * <p>A {@link StreamByteDistributor} needs to know the stream's window size in order to avoid allocating bytes
50 * if the window size is negative. The window size being {@code 0} may also be significant to determine when if
51 * an stream has been given a chance to write an empty frame, and also enables optimizations like not writing
52 * empty frames in some situations (don't write headers until data can also be written).
53 * @return the size of the stream's flow control window.
54 * @see Http2CodecUtil#streamableBytes(StreamState)
55 */
56 int windowSize();
57 }
58
59 /**
60 * Object that performs the writing of the bytes that have been allocated for a stream.
61 */
62 interface Writer {
63 /**
64 * Writes the allocated bytes for this stream.
65 * <p>
66 * Any {@link Throwable} thrown from this method is considered a programming error.
67 * A {@code GOAWAY} frame will be sent and the will be connection closed.
68 * @param stream the stream for which to perform the write.
69 * @param numBytes the number of bytes to write.
70 */
71 void write(Http2Stream stream, int numBytes);
72 }
73
74 /**
75 * Called when the streamable bytes for a stream has changed. Until this
76 * method is called for the first time for a give stream, the stream is assumed to have no
77 * streamable bytes.
78 */
79 void updateStreamableBytes(StreamState state);
80
81 /**
82 * Explicitly update the dependency tree. This method is called independently of stream state changes.
83 * @param childStreamId The stream identifier associated with the child stream.
84 * @param parentStreamId The stream identifier associated with the parent stream. May be {@code 0},
85 * to make {@code childStreamId} and immediate child of the connection.
86 * @param weight The weight which is used relative to other child streams for {@code parentStreamId}. This value
87 * must be between 1 and 256 (inclusive).
88 * @param exclusive If {@code childStreamId} should be the exclusive dependency of {@code parentStreamId}.
89 */
90 void updateDependencyTree(int childStreamId, int parentStreamId, short weight, boolean exclusive);
91
92 /**
93 * Distributes up to {@code maxBytes} to those streams containing streamable bytes and
94 * iterates across those streams to write the appropriate bytes. Criteria for
95 * traversing streams is undefined and it is up to the implementation to determine when to stop
96 * at a given stream.
97 *
98 * <p>The streamable bytes are not automatically updated by calling this method. It is up to the
99 * caller to indicate the number of bytes streamable after the write by calling
100 * {@link #updateStreamableBytes(StreamState)}.
101 *
102 * @param maxBytes the maximum number of bytes to write.
103 * @return {@code true} if there are still streamable bytes that have not yet been written,
104 * otherwise {@code false}.
105 * @throws Http2Exception If an internal exception occurs and internal connection state would otherwise be
106 * corrupted.
107 */
108 boolean distribute(int maxBytes, Writer writer) throws Http2Exception;
109 }