View Javadoc
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    * http://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  import io.netty.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 }