protocol-http2 0.11.3 → 0.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f02e8cbaee2f19317b390dc39177277184fe4a991b6780dcac1196303f63f2f
|
4
|
+
data.tar.gz: b10e1e173deddc82eb51f1f06d12df54b0c468b5db5154e13f0b01a2347ed182
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b326149b77c6064f93eb206aed282668ad2163f93f073ccba935e8c84c4e608d90ccc1d9f17841e88794915594e91aaaeb73b42c39175440a2603ed65a825275
|
7
|
+
data.tar.gz: f844428f6a8755569e915edf5089a56d039d21076e391c13d2766be0ceffbddbb58ea285ba143aac7f8668626c0b8509d7d37e15c80f891bcc402bef313c4987
|
@@ -20,13 +20,14 @@
|
|
20
20
|
|
21
21
|
require_relative 'framer'
|
22
22
|
require_relative 'dependency'
|
23
|
+
require_relative 'flow_controlled'
|
23
24
|
|
24
25
|
require 'protocol/hpack'
|
25
26
|
|
26
27
|
module Protocol
|
27
28
|
module HTTP2
|
28
29
|
class Connection
|
29
|
-
include
|
30
|
+
include FlowControlled
|
30
31
|
|
31
32
|
def initialize(framer, local_stream_id)
|
32
33
|
super()
|
@@ -465,6 +466,15 @@ module Protocol
|
|
465
466
|
end
|
466
467
|
end
|
467
468
|
|
469
|
+
# Traverse active streams in order of priority and allow them to consume the available flow-control window.
|
470
|
+
# @param amount [Integer] the amount of data to write. Defaults to the current window capacity.
|
471
|
+
def consume_window(size = self.available_size)
|
472
|
+
# Return if there is no window to consume:
|
473
|
+
return unless size > 0
|
474
|
+
|
475
|
+
@dependency.consume_window(size)
|
476
|
+
end
|
477
|
+
|
468
478
|
def receive_window_update(frame)
|
469
479
|
if frame.connection?
|
470
480
|
super
|
@@ -18,14 +18,12 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require_relative 'flow_control'
|
22
|
-
|
23
21
|
module Protocol
|
24
22
|
module HTTP2
|
25
23
|
DEFAULT_WEIGHT = 16
|
26
24
|
|
27
25
|
class Dependency
|
28
|
-
def initialize(connection, id, dependent_id = 0, weight = DEFAULT_WEIGHT
|
26
|
+
def initialize(connection, id, dependent_id = 0, weight = DEFAULT_WEIGHT)
|
29
27
|
@connection = connection
|
30
28
|
@id = id
|
31
29
|
|
@@ -33,8 +31,18 @@ module Protocol
|
|
33
31
|
@dependent_id = dependent_id
|
34
32
|
@weight = weight
|
35
33
|
|
36
|
-
|
37
|
-
|
34
|
+
@children = nil
|
35
|
+
|
36
|
+
# Cache of any associated stream:
|
37
|
+
@stream = nil
|
38
|
+
|
39
|
+
# Cache of children for window allocation:
|
40
|
+
@total_weight = 0
|
41
|
+
@ordered_children = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def <=> other
|
45
|
+
@weight <=> other.weight
|
38
46
|
end
|
39
47
|
|
40
48
|
def irrelevant?
|
@@ -62,34 +70,36 @@ module Protocol
|
|
62
70
|
attr_accessor :weight
|
63
71
|
|
64
72
|
def stream
|
65
|
-
@connection.streams[@id]
|
73
|
+
@stream ||= @connection.streams[@id]
|
66
74
|
end
|
67
75
|
|
68
|
-
def
|
69
|
-
|
70
|
-
# TODO this O(N) operation affects performance.
|
71
|
-
# It would be better to maintain a sorted list of children streams.
|
72
|
-
@children.map{|id, dependency| dependency.stream}.compact
|
73
|
-
end
|
76
|
+
def clear_cache!
|
77
|
+
@ordered_children = nil
|
74
78
|
end
|
75
79
|
|
76
80
|
def add_child(dependency)
|
77
81
|
@children ||= {}
|
78
82
|
@children[dependency.id] = dependency
|
83
|
+
|
84
|
+
self.clear_cache!
|
79
85
|
end
|
80
86
|
|
81
87
|
def remove_child(dependency)
|
82
88
|
@children&.delete(dependency.id)
|
89
|
+
|
90
|
+
self.clear_cache!
|
83
91
|
end
|
84
92
|
|
85
93
|
def exclusive_child(parent)
|
86
94
|
parent.children = @children
|
95
|
+
parent.clear_cache!
|
87
96
|
|
88
97
|
@children.each_value do |child|
|
89
98
|
child.dependent_id = parent.id
|
90
99
|
end
|
91
100
|
|
92
101
|
@children = {parent.id => parent}
|
102
|
+
self.clear_cache!
|
93
103
|
|
94
104
|
parent.dependent_id = @id
|
95
105
|
end
|
@@ -125,6 +135,8 @@ module Protocol
|
|
125
135
|
@dependent_id = dependent_id
|
126
136
|
|
127
137
|
self.parent.add_child(self)
|
138
|
+
else
|
139
|
+
self.parent&.clear_cache!
|
128
140
|
end
|
129
141
|
end
|
130
142
|
|
@@ -146,6 +158,34 @@ module Protocol
|
|
146
158
|
def receive_priority(frame)
|
147
159
|
self.process_priority(frame.unpack)
|
148
160
|
end
|
161
|
+
|
162
|
+
def ordered_children
|
163
|
+
unless @ordered_children
|
164
|
+
if @children and !@children.empty?
|
165
|
+
@ordered_children = @children.values.sort
|
166
|
+
@total_weight = @ordered_children.sum(&:weight)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
return @ordered_children
|
171
|
+
end
|
172
|
+
|
173
|
+
# Traverse active streams in order of priority and allow them to consume the available flow-control window.
|
174
|
+
# @param amount [Integer] the amount of data to write. Defaults to the current window capacity.
|
175
|
+
def consume_window(size)
|
176
|
+
# If there is an associated stream, give it priority:
|
177
|
+
if stream = self.stream
|
178
|
+
return if stream.window_updated(size)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Otherwise, allow the dependent children to use up the available window:
|
182
|
+
self.ordered_children&.each do |child|
|
183
|
+
# Compute the proportional allocation:
|
184
|
+
allocated = (child.weight * size) / @total_weight
|
185
|
+
|
186
|
+
child.consume_window(allocated) if allocated > 0
|
187
|
+
end
|
188
|
+
end
|
149
189
|
end
|
150
190
|
end
|
151
191
|
end
|
@@ -23,7 +23,7 @@ require_relative 'extensions/sum'
|
|
23
23
|
|
24
24
|
module Protocol
|
25
25
|
module HTTP2
|
26
|
-
module
|
26
|
+
module FlowControlled
|
27
27
|
def available_size
|
28
28
|
@remote_window.available
|
29
29
|
end
|
@@ -98,35 +98,9 @@ module Protocol
|
|
98
98
|
# The window has been expanded by the given amount.
|
99
99
|
# @param size [Integer] the maximum amount of data to send.
|
100
100
|
# @return [Boolean] whether the window update was used or not.
|
101
|
-
def window_updated(size
|
101
|
+
def window_updated(size)
|
102
102
|
return false
|
103
103
|
end
|
104
|
-
|
105
|
-
# Traverse active streams in order of priority and allow them to consume the available flow-control window.
|
106
|
-
# @todo This function can get slow when there are a lot of children [INEFFICIENT].
|
107
|
-
# @param amount [Integer] the amount of data to write. Defaults to the current window capacity.
|
108
|
-
def consume_window(size = self.available_size)
|
109
|
-
# Don't consume more than the available window size:
|
110
|
-
size = [self.available_size, size].min
|
111
|
-
# puts "consume_window(#{size}) local_window=#{@local_window} remote_window=#{@remote_window}"
|
112
|
-
|
113
|
-
# Return if there is no window to consume:
|
114
|
-
return unless size > 0
|
115
|
-
|
116
|
-
# Allow the current flow-controlled instance to use up the window:
|
117
|
-
if !self.window_updated(size) and children = self.children
|
118
|
-
children = children.sort_by(&:weight)
|
119
|
-
|
120
|
-
# This must always be at least >= `children.size`, since stream weight can't be 0.
|
121
|
-
total = children.sum(&:weight)
|
122
|
-
|
123
|
-
children.each do |child|
|
124
|
-
# Compute the proportional allocation:
|
125
|
-
allocated = (child.weight * size) / total
|
126
|
-
child.consume_window(allocated)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
104
|
end
|
131
105
|
end
|
132
106
|
end
|
@@ -72,7 +72,7 @@ module Protocol
|
|
72
72
|
#
|
73
73
|
# State transition methods use a trailing "!".
|
74
74
|
class Stream
|
75
|
-
include
|
75
|
+
include FlowControlled
|
76
76
|
|
77
77
|
def self.create(connection, id)
|
78
78
|
stream = self.new(connection, id)
|
@@ -124,10 +124,6 @@ module Protocol
|
|
124
124
|
@dependency.parent = stream.dependency
|
125
125
|
end
|
126
126
|
|
127
|
-
def children
|
128
|
-
@dependency&.streams
|
129
|
-
end
|
130
|
-
|
131
127
|
# The stream is being closed because the connection is being closed.
|
132
128
|
def close(error = nil)
|
133
129
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-http2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -118,7 +118,7 @@ files:
|
|
118
118
|
- lib/protocol/http2/error.rb
|
119
119
|
- lib/protocol/http2/extensions/sum.rb
|
120
120
|
- lib/protocol/http2/extensions/unpack.rb
|
121
|
-
- lib/protocol/http2/
|
121
|
+
- lib/protocol/http2/flow_controlled.rb
|
122
122
|
- lib/protocol/http2/frame.rb
|
123
123
|
- lib/protocol/http2/framer.rb
|
124
124
|
- lib/protocol/http2/goaway_frame.rb
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '0'
|
155
155
|
requirements: []
|
156
|
-
rubygems_version: 3.
|
156
|
+
rubygems_version: 3.1.2
|
157
157
|
signing_key:
|
158
158
|
specification_version: 4
|
159
159
|
summary: A low level implementation of the HTTP/2 protocol.
|