Class FlowController

java.lang.Object
io.github.mahmoudimus.http2.FlowController

public final class FlowController extends Object
Flow-control accounting for one connection (RFC 9113 §5.2, §6.9): the connection windows and a send and a receive window for each open stream. It only counts; when to send WINDOW_UPDATE, and how to share the send window between streams, is up to the caller.

Plain data with no locking: the caller serializes access (usually under the connection's lock), since frames are read on one thread and written from others.

  • Constructor Details

    • FlowController

      public FlowController(int localInitialWindowSize, int peerInitialWindowSize)
      Creates flow-control accounting with the agreed initial stream windows.
      Parameters:
      localInitialWindowSize - the SETTINGS_INITIAL_WINDOW_SIZE in force for what this endpoint receives (65535 until the peer acknowledges another)
      peerInitialWindowSize - the peer's SETTINGS_INITIAL_WINDOW_SIZE, for what this endpoint sends
    • FlowController

      public FlowController()
      Both directions at the protocol's initial 65535.
  • Method Details

    • addStream

      public void addStream(int streamId)
      Starts tracking a stream that has just opened.
      Parameters:
      streamId - the nonzero stream identifier
    • removeStream

      public void removeStream(int streamId)
      Stops tracking a closed stream. Frames for it still count against the connection windows.
      Parameters:
      streamId - the closed stream identifier
    • hasStream

      public boolean hasStream(int streamId)
      Checks whether a stream is tracked.
      Parameters:
      streamId - the stream identifier to query
      Returns:
      whether the stream is tracked
    • onDataReceived

      public void onDataReceived(int streamId, int length) throws Http2Exception
      Accounts for a received flow-controlled frame (DATA: Frame.Data.flowControlledLength()). The connection window is always debited; the stream's only if it is tracked.
      Parameters:
      streamId - the receiving stream identifier
      length - the flow-controlled octet count, including padding
      Throws:
      Http2Exception - if a receive window is exceeded
    • onWindowUpdateSent

      public void onWindowUpdateSent(int streamId, int increment) throws Http2Exception
      Credits a receive window for a WINDOW_UPDATE this endpoint sent (stream 0: the connection).
      Parameters:
      streamId - the stream identifier, or 0 for the connection
      increment - the positive credit sent
      Throws:
      Http2Exception - if the receive window would exceed 2^31-1
    • onWindowUpdateReceived

      public void onWindowUpdateReceived(int streamId, int increment) throws Http2Exception
      Credits a send window for a WINDOW_UPDATE received. Updates for streams not tracked are ignored.
      Parameters:
      streamId - the stream identifier, or 0 for the connection
      increment - the positive credit received
      Throws:
      Http2Exception - if the send window would exceed 2^31-1
    • sendable

      public int sendable(int streamId)
      How many flow-controlled octets the stream may send now: the smaller of its and the connection's window.
      Parameters:
      streamId - the stream identifier to query
      Returns:
      the available octet count, or 0 for an untracked stream
    • onDataSent

      public void onDataSent(int streamId, int length)
      Debits the send windows for a flow-controlled frame being sent.
      Parameters:
      streamId - the nonzero stream identifier
      length - the flow-controlled octet count, including padding
    • onPeerInitialWindowSize

      public void onPeerInitialWindowSize(int newSize) throws Http2Exception
      Applies a new SETTINGS_INITIAL_WINDOW_SIZE from the peer to every stream's send window.
      Parameters:
      newSize - the new nonnegative peer initial window size
      Throws:
      Http2Exception - if any send window would exceed 2^31-1
    • onLocalInitialWindowSize

      public void onLocalInitialWindowSize(int newSize) throws Http2Exception
      Applies this endpoint's new SETTINGS_INITIAL_WINDOW_SIZE, once acknowledged, to every receive window.
      Parameters:
      newSize - the new nonnegative local initial window size
      Throws:
      Http2Exception - if any receive window would exceed 2^31-1
    • connectionSendWindow

      public FlowControlWindow connectionSendWindow()
      Returns the connection send window.
      Returns:
      the mutable connection send window
    • connectionReceiveWindow

      public FlowControlWindow connectionReceiveWindow()
      Returns the connection receive window.
      Returns:
      the mutable connection receive window
    • streamSendWindow

      public FlowControlWindow streamSendWindow(int streamId)
      The stream's send window, or null if it is not tracked.
      Parameters:
      streamId - the stream identifier to query
      Returns:
      the mutable send window, or null if untracked
    • streamReceiveWindow

      public FlowControlWindow streamReceiveWindow(int streamId)
      The stream's receive window, or null if it is not tracked.
      Parameters:
      streamId - the stream identifier to query
      Returns:
      the mutable receive window, or null if untracked