Skip to content

Commit

Permalink
Extract window.rb.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Sep 28, 2024
1 parent 0290218 commit 361fc0a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 96 deletions.
104 changes: 104 additions & 0 deletions lib/protocol/http2/window.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2019-2024, by Samuel Williams.

module Protocol
module HTTP2
class Window
# @param capacity [Integer] The initial window size, typically from the settings.
def initialize(capacity = 0xFFFF)
# This is the main field required:
@available = capacity

# These two fields are primarily used for efficiently sending window updates:
@used = 0
@capacity = capacity
end

# The window is completely full?
def full?
@available <= 0
end

attr :used
attr :capacity

# When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value.
def capacity= value
difference = value - @capacity

# An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow-control window to exceed the maximum size as a connection error of type FLOW_CONTROL_ERROR.
if (@available + difference) > MAXIMUM_ALLOWED_WINDOW_SIZE
raise FlowControlError, "Changing window size by #{difference} caused overflow: #{@available + difference} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
end

@available += difference
@capacity = value
end

def consume(amount)
@available -= amount
@used += amount
end

attr :available

def available?
@available > 0
end

def expand(amount)
available = @available + amount

if available > MAXIMUM_ALLOWED_WINDOW_SIZE
raise FlowControlError, "Expanding window by #{amount} caused overflow: #{available} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
end

# puts "expand(#{amount}) @available=#{@available}"
@available += amount
@used -= amount
end

def wanted
@used
end

def limited?
@available < (@capacity / 2)
end

def inspect
"\#<#{self.class} used=#{@used} available=#{@available} capacity=#{@capacity}>"
end
end

# This is a window which efficiently maintains a desired capacity.
class LocalWindow < Window
def initialize(capacity = 0xFFFF, desired: nil)
super(capacity)

@desired = desired
end

attr_accessor :desired

def wanted
if @desired
# We must send an update which allows at least @desired bytes to be sent.
(@desired - @capacity) + @used
else
@used
end
end

def limited?
if @desired
@available < @desired
else
super
end
end
end
end
end
97 changes: 1 addition & 96 deletions lib/protocol/http2/window_update_frame.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,105 +4,10 @@
# Copyright, 2019-2024, by Samuel Williams.

require_relative "frame"
require_relative "window"

module Protocol
module HTTP2
class Window
# @param capacity [Integer] The initial window size, typically from the settings.
def initialize(capacity = 0xFFFF)
# This is the main field required:
@available = capacity

# These two fields are primarily used for efficiently sending window updates:
@used = 0
@capacity = capacity
end

# The window is completely full?
def full?
@available <= 0
end

attr :used
attr :capacity

# When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value.
def capacity= value
difference = value - @capacity

# An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow-control window to exceed the maximum size as a connection error of type FLOW_CONTROL_ERROR.
if (@available + difference) > MAXIMUM_ALLOWED_WINDOW_SIZE
raise FlowControlError, "Changing window size by #{difference} caused overflow: #{@available + difference} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
end

@available += difference
@capacity = value
end

def consume(amount)
@available -= amount
@used += amount
end

attr :available

def available?
@available > 0
end

def expand(amount)
available = @available + amount

if available > MAXIMUM_ALLOWED_WINDOW_SIZE
raise FlowControlError, "Expanding window by #{amount} caused overflow: #{available} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
end

# puts "expand(#{amount}) @available=#{@available}"
@available += amount
@used -= amount
end

def wanted
@used
end

def limited?
@available < (@capacity / 2)
end

def inspect
"\#<#{self.class} used=#{@used} available=#{@available} capacity=#{@capacity}>"
end
end

# This is a window which efficiently maintains a desired capacity.
class LocalWindow < Window
def initialize(capacity = 0xFFFF, desired: nil)
super(capacity)

@desired = desired
end

attr_accessor :desired

def wanted
if @desired
# We must send an update which allows at least @desired bytes to be sent.
(@desired - @capacity) + @used
else
@used
end
end

def limited?
if @desired
@available < @desired
else
super
end
end
end

# The WINDOW_UPDATE frame is used to implement flow control.
#
# +-+-------------------------------------------------------------+
Expand Down

0 comments on commit 361fc0a

Please sign in to comment.