protocol-http2 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
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.
|