class Protocol::HTTP2::Dependency

Attributes

children[RW]

The dependent children.

connection[R]

The connection this stream belongs to.

id[R]

Stream ID (odd for client initiated streams, even otherwise).

parent[RW]

The parent dependency.

weight[RW]

The weight of the stream relative to other siblings.

Public Class Methods

create(connection, id, priority = nil) click to toggle source
# File lib/protocol/http2/dependency.rb, line 26
def self.create(connection, id, priority = nil)
        weight = DEFAULT_WEIGHT
        exclusive = false
        
        if priority
                if parent = connection.dependencies[priority.stream_dependency]
                        exclusive = priority.exclusive
                end
                
                weight = priority.weight
        end
        
        if parent.nil?
                parent = connection.dependency
        end
        
        dependency = self.new(connection, id, weight)
        
        connection.dependencies[id] = dependency
        
        if exclusive
                parent.exclusive_child(dependency)
        else
                parent.add_child(dependency)
        end
        
        return dependency
end
new(connection, id, weight = DEFAULT_WEIGHT) click to toggle source
# File lib/protocol/http2/dependency.rb, line 55
def initialize(connection, id, weight = DEFAULT_WEIGHT)
        @connection = connection
        @id = id
        
        @parent = nil
        @children = nil
        
        @weight = weight
        
        # Cache of any associated stream:
        @stream = nil
        
        # Cache of children for window allocation:
        @total_weight = 0
        @ordered_children = nil
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/protocol/http2/dependency.rb, line 72
def <=> other
        @weight <=> other.weight
end
add_child(dependency) click to toggle source
# File lib/protocol/http2/dependency.rb, line 113
def add_child(dependency)
        @children ||= {}
        @children[dependency.id] = dependency
        
        dependency.parent = self
        
        self.clear_cache!
end
clear_cache!() click to toggle source
# File lib/protocol/http2/dependency.rb, line 95
def clear_cache!
        @ordered_children = nil
end
consume_window(size) click to toggle source

Traverse active streams in order of priority and allow them to consume the available flow-control window. @param amount [Integer] the amount of data to write. Defaults to the current window capacity.

# File lib/protocol/http2/dependency.rb, line 206
def consume_window(size)
        # If there is an associated stream, give it priority:
        if stream = self.stream
                return if stream.window_updated(size)
        end
        
        # Otherwise, allow the dependent children to use up the available window:
        self.ordered_children&.each do |child|
                # Compute the proportional allocation:
                allocated = (child.weight * size) / @total_weight
                
                child.consume_window(allocated) if allocated > 0
        end
end
delete!() click to toggle source
# File lib/protocol/http2/dependency.rb, line 99
def delete!
        @connection.dependencies.delete(@id)
        
        @parent.remove_child(self)
        
        @children&.each do |id, child|
                parent.add_child(child)
        end
        
        @connection = nil
        @parent = nil
        @children = nil
end
exclusive_child(parent) click to toggle source

An exclusive flag allows for the insertion of a new level of dependencies. The exclusive flag causes the stream to become the sole dependency of its parent stream, causing other dependencies to become dependent on the exclusive stream. @param parent [Dependency] the dependency which will be inserted, taking control of all current children.

# File lib/protocol/http2/dependency.rb, line 130
def exclusive_child(parent)
        parent.children = @children
        
        @children&.each_value do |child|
                child.parent = parent
        end
        
        parent.clear_cache!
        
        @children = {parent.id => parent}
        self.clear_cache!
        
        parent.parent = self
end
ordered_children() click to toggle source
# File lib/protocol/http2/dependency.rb, line 193
def ordered_children
        unless @ordered_children
                if @children and !@children.empty?
                        @ordered_children = @children.values.sort
                        @total_weight = @ordered_children.sum(&:weight)
                end
        end
        
        return @ordered_children
end
print_hierarchy(buffer, indent: 0) click to toggle source
priority(exclusive = false) click to toggle source

The current local priority of the stream.

# File lib/protocol/http2/dependency.rb, line 175
def priority(exclusive = false)
        Priority.new(exclusive, @parent.id, @weight)
end
priority=(priority) click to toggle source

Change the priority of the stream both locally and remotely.

# File lib/protocol/http2/dependency.rb, line 169
def priority= priority
        send_priority(priority)
        process_priority(priority)
end
process_priority(priority) click to toggle source
# File lib/protocol/http2/dependency.rb, line 145
def process_priority(priority)
        dependent_id = priority.stream_dependency
        
        if dependent_id == @id
                raise ProtocolError, "Stream priority for stream id #{@id} cannot depend on itself!"
        end
        
        @weight = priority.weight
        
        # We essentially ignore `dependent_id` if the dependency does not exist:
        if parent = @connection.dependencies[dependent_id]
                if priority.exclusive
                        @parent.remove_child(self)
                        
                        parent.exclusive_child(self)
                elsif !@parent.equal?(parent)
                        @parent.remove_child(self)
                        
                        parent.add_child(self)
                end
        end
end
receive_priority(frame) click to toggle source
# File lib/protocol/http2/dependency.rb, line 183
def receive_priority(frame)
        self.process_priority(frame.unpack)
end
remove_child(dependency) click to toggle source
# File lib/protocol/http2/dependency.rb, line 122
def remove_child(dependency)
        @children&.delete(dependency.id)
        
        self.clear_cache!
end
send_priority(priority) click to toggle source
# File lib/protocol/http2/dependency.rb, line 179
def send_priority(priority)
        @connection.send_priority(@id, priority)
end
stream() click to toggle source
# File lib/protocol/http2/dependency.rb, line 91
def stream
        @stream ||= @connection.streams[@id]
end
to_s() click to toggle source
# File lib/protocol/http2/dependency.rb, line 221
def to_s
        "\#<#{self.class} id=#{@id} parent id=#{@parent&.id} weight=#{@weight} #{@children&.size || 0} children>"
end
total_weight() click to toggle source
# File lib/protocol/http2/dependency.rb, line 187
def total_weight
        self.orderd_children
        
        return @total_weight
end