biryani 0.0.1 → 0.0.2
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 +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +7 -2
- data/example/echo.rb +2 -2
- data/example/hello_world.rb +2 -2
- data/lib/biryani/connection.rb +91 -96
- data/lib/biryani/data_buffer.rb +26 -16
- data/lib/biryani/frame/headers.rb +0 -2
- data/lib/biryani/http_response.rb +4 -20
- data/lib/biryani/state.rb +14 -2
- data/lib/biryani/streams_context.rb +60 -5
- data/lib/biryani/utils.rb +8 -0
- data/lib/biryani/version.rb +1 -1
- data/lib/biryani/window.rb +11 -13
- data/lib/biryani.rb +3 -2
- data/spec/connection/handle_connection_window_update_spec.rb +1 -1
- data/spec/connection/handle_rst_stream_spec.rb +2 -2
- data/spec/connection/handle_settings_spec.rb +8 -2
- data/spec/connection/handle_stream_window_update_spec.rb +2 -2
- data/spec/connection/send_spec.rb +34 -44
- data/spec/connection/transition_state_send_spec.rb +3 -3
- data/spec/data_buffer_spec.rb +43 -43
- data/spec/streams_context_spec.rb +79 -0
- metadata +4 -5
- data/spec/connection/close_all_streams_spec.rb +0 -17
- data/spec/connection/remove_closed_streams_spec.rb +0 -51
|
@@ -5,11 +5,13 @@ module Biryani
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
# @param stream_id [Integer]
|
|
8
|
+
# @param send_initial_window_size [Integer]
|
|
9
|
+
# @param recv_initial_window_size [Integer]
|
|
8
10
|
# @param proc [Proc]
|
|
9
11
|
#
|
|
10
12
|
# @return [StreamContext]
|
|
11
|
-
def new_context(stream_id, proc)
|
|
12
|
-
ctx = StreamContext.new(stream_id, proc)
|
|
13
|
+
def new_context(stream_id, send_initial_window_size, recv_initial_window_size, proc)
|
|
14
|
+
ctx = StreamContext.new(stream_id, send_initial_window_size, recv_initial_window_size, proc)
|
|
13
15
|
@h[stream_id] = ctx
|
|
14
16
|
ctx
|
|
15
17
|
end
|
|
@@ -54,18 +56,71 @@ module Biryani
|
|
|
54
56
|
def last_stream_id
|
|
55
57
|
@h.reject { |_, ctx| ctx.idle? }.keys.max || 0
|
|
56
58
|
end
|
|
59
|
+
|
|
60
|
+
# @param stream_id [Integer]
|
|
61
|
+
# @param data [String]
|
|
62
|
+
# @param send_window [Window]
|
|
63
|
+
# @param max_frame_size [Integer]
|
|
64
|
+
#
|
|
65
|
+
# @return [Array<Object>] frames
|
|
66
|
+
# @return [String]
|
|
67
|
+
def sendable_data_frames(stream_id, data, send_window, max_frame_size)
|
|
68
|
+
len = [data.bytesize, send_window.length, @h[stream_id].send_window.length].min
|
|
69
|
+
|
|
70
|
+
payload = data[0...len]
|
|
71
|
+
remains = data[len..] || ''
|
|
72
|
+
|
|
73
|
+
len = (len + max_frame_size - 1) / max_frame_size
|
|
74
|
+
frames = payload.gsub(/.{1,#{max_frame_size}}/m).with_index.map do |s, index|
|
|
75
|
+
end_stream = remains.empty? && index == len - 1
|
|
76
|
+
Frame::Data.new(end_stream, stream_id, s, nil)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
[frames, remains]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @param data_buffer [DataBuffer]
|
|
83
|
+
def remove_closed(data_buffer)
|
|
84
|
+
closed_ids = closed_stream_ids.filter { |id| !data_buffer.has?(id) }
|
|
85
|
+
closed_ids.each do |id|
|
|
86
|
+
@h[id].tx.close
|
|
87
|
+
@h[id].stream.rx << nil
|
|
88
|
+
@h[id].fragment.close
|
|
89
|
+
@h[id].content.close
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def close_all
|
|
94
|
+
each do |ctx|
|
|
95
|
+
ctx.tx.close
|
|
96
|
+
ctx.fragment.close
|
|
97
|
+
ctx.content.close
|
|
98
|
+
ctx.state.close
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def clear_all
|
|
103
|
+
each do |ctx|
|
|
104
|
+
ctx.tx.close
|
|
105
|
+
ctx.stream.rx << nil
|
|
106
|
+
ctx.fragment.close
|
|
107
|
+
ctx.content.close
|
|
108
|
+
end
|
|
109
|
+
end
|
|
57
110
|
end
|
|
58
111
|
|
|
59
112
|
class StreamContext
|
|
60
113
|
attr_accessor :stream, :tx, :send_window, :recv_window, :fragment, :content, :state
|
|
61
114
|
|
|
62
115
|
# @param stream_id [Integer]
|
|
116
|
+
# @param send_initial_window_size [Integer]
|
|
117
|
+
# @param recv_initial_window_size [Integer]
|
|
63
118
|
# @param proc [Proc]
|
|
64
|
-
def initialize(stream_id, proc)
|
|
119
|
+
def initialize(stream_id, send_initial_window_size, recv_initial_window_size, proc)
|
|
65
120
|
@tx = Ractor::Port.new
|
|
66
121
|
@stream = Stream.new(@tx, stream_id, proc)
|
|
67
|
-
@send_window = Window.new
|
|
68
|
-
@recv_window = Window.new
|
|
122
|
+
@send_window = Window.new(send_initial_window_size)
|
|
123
|
+
@recv_window = Window.new(recv_initial_window_size)
|
|
69
124
|
@fragment = StringIO.new
|
|
70
125
|
@content = StringIO.new
|
|
71
126
|
@state = State.new
|
data/lib/biryani/version.rb
CHANGED
data/lib/biryani/window.rb
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
module Biryani
|
|
2
2
|
class Window
|
|
3
|
-
|
|
4
|
-
@window = 2**16 - 1
|
|
5
|
-
end
|
|
3
|
+
attr_reader :length
|
|
6
4
|
|
|
7
|
-
# @param
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@window > length
|
|
5
|
+
# @param initial_window_size [Integer]
|
|
6
|
+
def initialize(initial_window_size)
|
|
7
|
+
@length = initial_window_size
|
|
8
|
+
@capacity = initial_window_size
|
|
12
9
|
end
|
|
13
10
|
|
|
14
11
|
# @param length [Integer]
|
|
15
12
|
def consume!(length)
|
|
16
|
-
@
|
|
13
|
+
@length -= length
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
# @param length [Integer]
|
|
20
17
|
def increase!(length)
|
|
21
|
-
@
|
|
18
|
+
@length += length
|
|
22
19
|
end
|
|
23
20
|
|
|
24
|
-
# @
|
|
25
|
-
def
|
|
26
|
-
@
|
|
21
|
+
# @param initial_window_size [Integer]
|
|
22
|
+
def update!(initial_window_size)
|
|
23
|
+
@length = initial_window_size - @capacity + @length
|
|
24
|
+
@capacity = initial_window_size
|
|
27
25
|
end
|
|
28
26
|
end
|
|
29
27
|
end
|
data/lib/biryani.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require 'stringio'
|
|
2
2
|
require 'uri'
|
|
3
3
|
|
|
4
|
-
require_relative 'biryani/connection'
|
|
5
4
|
require_relative 'biryani/connection_error'
|
|
5
|
+
require_relative 'biryani/connection'
|
|
6
6
|
require_relative 'biryani/data_buffer'
|
|
7
7
|
require_relative 'biryani/frame'
|
|
8
8
|
require_relative 'biryani/hpack'
|
|
@@ -10,8 +10,9 @@ require_relative 'biryani/http_request'
|
|
|
10
10
|
require_relative 'biryani/http_response'
|
|
11
11
|
require_relative 'biryani/server'
|
|
12
12
|
require_relative 'biryani/state'
|
|
13
|
-
require_relative 'biryani/streams_context'
|
|
14
13
|
require_relative 'biryani/stream_error'
|
|
15
14
|
require_relative 'biryani/stream'
|
|
15
|
+
require_relative 'biryani/streams_context'
|
|
16
|
+
require_relative 'biryani/utils'
|
|
16
17
|
require_relative 'biryani/version'
|
|
17
18
|
require_relative 'biryani/window'
|
|
@@ -7,8 +7,8 @@ RSpec.describe Connection do
|
|
|
7
7
|
end
|
|
8
8
|
let(:streams_ctx) do
|
|
9
9
|
streams_ctx = StreamsContext.new
|
|
10
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
11
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
10
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
11
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
12
12
|
streams_ctx
|
|
13
13
|
end
|
|
14
14
|
it 'should handle' do
|
|
@@ -8,12 +8,18 @@ RSpec.describe Connection do
|
|
|
8
8
|
let(:decoder) do
|
|
9
9
|
HPACK::Decoder.new(4_096)
|
|
10
10
|
end
|
|
11
|
+
let(:streams_ctx) do
|
|
12
|
+
streams_ctx = StreamsContext.new
|
|
13
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
14
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
15
|
+
streams_ctx
|
|
16
|
+
end
|
|
11
17
|
|
|
12
18
|
let(:settings1) do
|
|
13
19
|
Frame::Settings.new(false, 0, { SettingsID::SETTINGS_HEADER_TABLE_SIZE => 8_192 })
|
|
14
20
|
end
|
|
15
21
|
it 'should handle' do
|
|
16
|
-
reply_settings = Connection.handle_settings(settings1, send_settings, decoder)
|
|
22
|
+
reply_settings = Connection.handle_settings(settings1, send_settings, decoder, streams_ctx)
|
|
17
23
|
expect(reply_settings.ack?).to eq true
|
|
18
24
|
expect(reply_settings.setting.empty?).to eq true
|
|
19
25
|
expect(send_settings[SettingsID::SETTINGS_MAX_CONCURRENT_STREAMS]).to eq 0xffffffff
|
|
@@ -25,7 +31,7 @@ RSpec.describe Connection do
|
|
|
25
31
|
Frame::Settings.new(true, 0, {})
|
|
26
32
|
end
|
|
27
33
|
it 'should handle' do
|
|
28
|
-
expect(Connection.handle_settings(settings2, send_settings, decoder)).to eq nil
|
|
34
|
+
expect(Connection.handle_settings(settings2, send_settings, decoder, streams_ctx)).to eq nil
|
|
29
35
|
end
|
|
30
36
|
end
|
|
31
37
|
end
|
|
@@ -7,8 +7,8 @@ RSpec.describe Connection do
|
|
|
7
7
|
end
|
|
8
8
|
let(:streams_ctx) do
|
|
9
9
|
streams_ctx = StreamsContext.new
|
|
10
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
11
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
10
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
11
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
12
12
|
streams_ctx
|
|
13
13
|
end
|
|
14
14
|
it 'should handle' do
|
|
@@ -10,29 +10,25 @@ RSpec.describe Connection do
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
let(:headers1) do
|
|
13
|
-
Frame::Headers.new(true,
|
|
14
|
-
end
|
|
15
|
-
let(:data1) do
|
|
16
|
-
Frame::Data.new(true, 2, 'Hello, world!', 'Howdy!')
|
|
13
|
+
Frame::Headers.new(true, true, 2, nil, nil, 'this is dummy'.b, nil)
|
|
17
14
|
end
|
|
18
15
|
let(:send_window1) do
|
|
19
|
-
Window.new
|
|
16
|
+
Window.new(65_535)
|
|
20
17
|
end
|
|
21
18
|
let(:streams_ctx1) do
|
|
22
19
|
streams_ctx = StreamsContext.new
|
|
23
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
24
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
20
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
21
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
25
22
|
streams_ctx
|
|
26
23
|
end
|
|
27
24
|
it 'should send' do
|
|
28
25
|
streams_ctx1[2].state.transition!(headers1, :recv)
|
|
29
|
-
|
|
30
|
-
Connection.
|
|
31
|
-
|
|
32
|
-
expect(
|
|
33
|
-
expect(
|
|
34
|
-
expect(streams_ctx1[
|
|
35
|
-
expect(streams_ctx1[2].send_window.length).to eq 2**16 - 21
|
|
26
|
+
Connection.send_headers(io, 2, "\x88".b, false, 16_384, streams_ctx1)
|
|
27
|
+
Connection.send_data(io, 2, 'Hello, world!'.b, send_window1, 16_384, streams_ctx1, data_buffer)
|
|
28
|
+
expect(io.string.force_encoding(Encoding::ASCII_8BIT)).to eq "\x00\x00\x01\x01\x04\x00\x00\x00\x02\x88\x00\x00\x0d\x00\x01\x00\x00\x00\x02Hello, world!".b
|
|
29
|
+
expect(send_window1.length).to eq 65_535 - 13
|
|
30
|
+
expect(streams_ctx1[1].send_window.length).to eq 65_535
|
|
31
|
+
expect(streams_ctx1[2].send_window.length).to eq 65_535 - 13
|
|
36
32
|
expect(data_buffer.length).to eq 0
|
|
37
33
|
end
|
|
38
34
|
|
|
@@ -40,46 +36,43 @@ RSpec.describe Connection do
|
|
|
40
36
|
Frame::Headers.new(true, true, 1, nil, nil, 'this is dummy', nil)
|
|
41
37
|
end
|
|
42
38
|
let(:send_window2) do
|
|
43
|
-
Window.new
|
|
39
|
+
Window.new(65_535)
|
|
44
40
|
end
|
|
45
41
|
let(:streams_ctx2) do
|
|
46
42
|
streams_ctx = StreamsContext.new
|
|
47
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
48
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
43
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
44
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
49
45
|
streams_ctx
|
|
50
46
|
end
|
|
51
47
|
it 'should send' do
|
|
52
48
|
streams_ctx2[1].state.transition!(headers2, :recv)
|
|
53
|
-
Connection.
|
|
54
|
-
expect(io.string).to eq "\x00\x00\
|
|
55
|
-
expect(send_window2.length).to eq
|
|
56
|
-
expect(streams_ctx2[1].send_window.length).to eq
|
|
57
|
-
expect(streams_ctx2[2].send_window.length).to eq
|
|
49
|
+
Connection.send_headers(io, 1, "\x88".b, true, 16_384, streams_ctx2)
|
|
50
|
+
expect(io.string.force_encoding(Encoding::ASCII_8BIT)).to eq "\x00\x00\x01\x01\x05\x00\x00\x00\x01\x88".b
|
|
51
|
+
expect(send_window2.length).to eq 65_535
|
|
52
|
+
expect(streams_ctx2[1].send_window.length).to eq 65_535
|
|
53
|
+
expect(streams_ctx2[2].send_window.length).to eq 65_535
|
|
58
54
|
expect(data_buffer.length).to eq 0
|
|
59
55
|
end
|
|
60
56
|
|
|
61
57
|
let(:headers3) do
|
|
62
58
|
Frame::Headers.new(true, true, 2, nil, nil, 'this is dummy', nil)
|
|
63
59
|
end
|
|
64
|
-
let(:data3) do
|
|
65
|
-
Frame::Data.new(false, 2, 'Hello, world!', 'Howdy!')
|
|
66
|
-
end
|
|
67
60
|
let(:send_window3) do
|
|
68
|
-
Window.new
|
|
61
|
+
Window.new(65_535)
|
|
69
62
|
end
|
|
70
63
|
let(:streams_ctx3) do
|
|
71
64
|
streams_ctx = StreamsContext.new
|
|
72
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
73
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
74
|
-
streams_ctx[2].send_window.consume!(
|
|
65
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
66
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
67
|
+
streams_ctx[2].send_window.consume!(65_535)
|
|
75
68
|
streams_ctx
|
|
76
69
|
end
|
|
77
70
|
it 'should send' do
|
|
78
71
|
streams_ctx3[2].state.transition!(headers3, :recv)
|
|
79
|
-
Connection.
|
|
80
|
-
expect(io.string).to eq ''
|
|
81
|
-
expect(send_window3.length).to eq
|
|
82
|
-
expect(streams_ctx3[1].send_window.length).to eq
|
|
72
|
+
Connection.send_data(io, 2, 'Hello, world!'.b, send_window3, 16_384, streams_ctx3, data_buffer)
|
|
73
|
+
expect(io.string.force_encoding(Encoding::ASCII_8BIT)).to eq ''.b
|
|
74
|
+
expect(send_window3.length).to eq 65_535
|
|
75
|
+
expect(streams_ctx3[1].send_window.length).to eq 65_535
|
|
83
76
|
expect(streams_ctx3[2].send_window.length).to eq 0
|
|
84
77
|
expect(data_buffer.length).to eq 1
|
|
85
78
|
end
|
|
@@ -87,27 +80,24 @@ RSpec.describe Connection do
|
|
|
87
80
|
let(:headers4) do
|
|
88
81
|
Frame::Headers.new(true, true, 2, nil, nil, 'this is dummy', nil)
|
|
89
82
|
end
|
|
90
|
-
let(:data4) do
|
|
91
|
-
Frame::Data.new(false, 2, 'Hello, world!', 'Howdy!')
|
|
92
|
-
end
|
|
93
83
|
let(:send_window4) do
|
|
94
|
-
send_window = Window.new
|
|
95
|
-
send_window.consume!(
|
|
84
|
+
send_window = Window.new(65_535)
|
|
85
|
+
send_window.consume!(65_535)
|
|
96
86
|
send_window
|
|
97
87
|
end
|
|
98
88
|
let(:streams_ctx4) do
|
|
99
89
|
streams_ctx = StreamsContext.new
|
|
100
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
101
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
90
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
91
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
102
92
|
streams_ctx
|
|
103
93
|
end
|
|
104
94
|
it 'should send' do
|
|
105
95
|
streams_ctx4[2].state.transition!(headers4, :recv)
|
|
106
|
-
Connection.
|
|
107
|
-
expect(io.string).to eq ''
|
|
96
|
+
Connection.send_data(io, 2, 'Hello, world!'.b, send_window4, 16_384, streams_ctx4, data_buffer)
|
|
97
|
+
expect(io.string.force_encoding(Encoding::ASCII_8BIT)).to eq ''.b
|
|
108
98
|
expect(send_window4.length).to eq 0
|
|
109
|
-
expect(streams_ctx4[1].send_window.length).to eq
|
|
110
|
-
expect(streams_ctx4[2].send_window.length).to eq
|
|
99
|
+
expect(streams_ctx4[1].send_window.length).to eq 65_535
|
|
100
|
+
expect(streams_ctx4[2].send_window.length).to eq 65_535
|
|
111
101
|
expect(data_buffer.length).to eq 1
|
|
112
102
|
end
|
|
113
103
|
end
|
|
@@ -4,8 +4,8 @@ RSpec.describe Connection do
|
|
|
4
4
|
context 'transition_state_send' do
|
|
5
5
|
let(:streams_ctx) do
|
|
6
6
|
streams_ctx = StreamsContext.new
|
|
7
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
8
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
7
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
8
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
9
9
|
streams_ctx
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -21,7 +21,7 @@ RSpec.describe Connection do
|
|
|
21
21
|
it 'should transition' do
|
|
22
22
|
streams_ctx[1].state.transition!(headers, :recv)
|
|
23
23
|
streams_ctx[2].state.transition!(headers, :recv)
|
|
24
|
-
|
|
24
|
+
streams_ctx.close_all
|
|
25
25
|
expect { streams_ctx[1].tx << nil }.to raise_error Ractor::ClosedError
|
|
26
26
|
expect { streams_ctx[2].tx << nil }.to raise_error Ractor::ClosedError
|
|
27
27
|
end
|
data/spec/data_buffer_spec.rb
CHANGED
|
@@ -6,125 +6,125 @@ RSpec.describe DataBuffer do
|
|
|
6
6
|
DataBuffer.new
|
|
7
7
|
end
|
|
8
8
|
let(:send_window1) do
|
|
9
|
-
Window.new
|
|
9
|
+
Window.new(65_535)
|
|
10
10
|
end
|
|
11
11
|
let(:streams_ctx1) do
|
|
12
12
|
streams_ctx = StreamsContext.new
|
|
13
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
14
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
13
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
14
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
15
15
|
streams_ctx
|
|
16
16
|
end
|
|
17
17
|
it 'should take' do
|
|
18
|
-
expect(data_buffer1.take!(send_window1, streams_ctx1).length).to eq 0
|
|
19
|
-
expect(send_window1.length).to eq
|
|
20
|
-
expect(streams_ctx1[1].send_window.length).to eq
|
|
21
|
-
expect(streams_ctx1[2].send_window.length).to eq
|
|
18
|
+
expect(data_buffer1.take!(send_window1, streams_ctx1, 16_384).length).to eq 0
|
|
19
|
+
expect(send_window1.length).to eq 65_535
|
|
20
|
+
expect(streams_ctx1[1].send_window.length).to eq 65_535
|
|
21
|
+
expect(streams_ctx1[2].send_window.length).to eq 65_535
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
let(:data_buffer2) do
|
|
25
25
|
data_buffer = DataBuffer.new
|
|
26
|
-
data_buffer
|
|
27
|
-
data_buffer
|
|
26
|
+
data_buffer.store(1, 'one')
|
|
27
|
+
data_buffer.store(2, 'two')
|
|
28
28
|
data_buffer
|
|
29
29
|
end
|
|
30
30
|
let(:send_window2) do
|
|
31
|
-
Window.new
|
|
31
|
+
Window.new(65_535)
|
|
32
32
|
end
|
|
33
33
|
let(:streams_ctx2) do
|
|
34
34
|
streams_ctx = StreamsContext.new
|
|
35
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
36
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
35
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
36
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
37
37
|
streams_ctx
|
|
38
38
|
end
|
|
39
39
|
it 'should take' do
|
|
40
|
-
datas = data_buffer2.take!(send_window2, streams_ctx2)
|
|
40
|
+
datas = data_buffer2.take!(send_window2, streams_ctx2, 16_384)
|
|
41
41
|
expect(datas.length).to eq 2
|
|
42
42
|
expect(datas.map(&:stream_id)).to eq [1, 2]
|
|
43
43
|
expect(datas.map(&:data)).to eq %w[one two]
|
|
44
|
-
expect(send_window2.length).to eq
|
|
45
|
-
expect(streams_ctx2[1].send_window.length).to eq
|
|
46
|
-
expect(streams_ctx2[2].send_window.length).to eq
|
|
44
|
+
expect(send_window2.length).to eq 65_535 - 6
|
|
45
|
+
expect(streams_ctx2[1].send_window.length).to eq 65_535 - 3
|
|
46
|
+
expect(streams_ctx2[2].send_window.length).to eq 65_535 - 3
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
let(:data_buffer3) do
|
|
50
50
|
data_buffer = DataBuffer.new
|
|
51
|
-
data_buffer
|
|
51
|
+
data_buffer.store(2, 'two')
|
|
52
52
|
data_buffer
|
|
53
53
|
end
|
|
54
54
|
let(:send_window3) do
|
|
55
|
-
Window.new
|
|
55
|
+
Window.new(65_535)
|
|
56
56
|
end
|
|
57
57
|
let(:streams_ctx3) do
|
|
58
58
|
streams_ctx = StreamsContext.new
|
|
59
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
60
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
59
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
60
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
61
61
|
streams_ctx
|
|
62
62
|
end
|
|
63
63
|
it 'should take' do
|
|
64
|
-
datas = data_buffer3.take!(send_window3, streams_ctx3)
|
|
64
|
+
datas = data_buffer3.take!(send_window3, streams_ctx3, 16_384)
|
|
65
65
|
expect(datas.length).to eq 1
|
|
66
66
|
expect(datas.first.stream_id).to eq 2
|
|
67
67
|
expect(datas.first.data).to eq 'two'
|
|
68
|
-
expect(send_window3.length).to eq
|
|
69
|
-
expect(streams_ctx3[1].send_window.length).to eq
|
|
70
|
-
expect(streams_ctx3[2].send_window.length).to eq
|
|
68
|
+
expect(send_window3.length).to eq 65_535 - 3
|
|
69
|
+
expect(streams_ctx3[1].send_window.length).to eq 65_535
|
|
70
|
+
expect(streams_ctx3[2].send_window.length).to eq 65_535 - 3
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
let(:data_buffer4) do
|
|
74
74
|
data_buffer = DataBuffer.new
|
|
75
|
-
data_buffer
|
|
76
|
-
data_buffer
|
|
75
|
+
data_buffer.store(1, 'one')
|
|
76
|
+
data_buffer.store(2, 'two')
|
|
77
77
|
data_buffer
|
|
78
78
|
end
|
|
79
79
|
let(:send_window4) do
|
|
80
|
-
Window.new
|
|
80
|
+
Window.new(65_535)
|
|
81
81
|
end
|
|
82
82
|
let(:streams_ctx4) do
|
|
83
83
|
streams_ctx = StreamsContext.new
|
|
84
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
85
|
-
streams_ctx[1].send_window.consume!(
|
|
86
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
84
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
85
|
+
streams_ctx[1].send_window.consume!(65_535)
|
|
86
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
87
87
|
streams_ctx
|
|
88
88
|
end
|
|
89
89
|
it 'should take' do
|
|
90
|
-
datas = data_buffer4.take!(send_window4, streams_ctx4)
|
|
90
|
+
datas = data_buffer4.take!(send_window4, streams_ctx4, 16_384)
|
|
91
91
|
expect(datas.length).to eq 1
|
|
92
92
|
expect(datas.first.stream_id).to eq 2
|
|
93
93
|
expect(datas.first.data).to eq 'two'
|
|
94
|
-
expect(send_window4.length).to eq
|
|
94
|
+
expect(send_window4.length).to eq 65_535 - 3
|
|
95
95
|
expect(streams_ctx4[1].send_window.length).to eq 0
|
|
96
|
-
expect(streams_ctx4[2].send_window.length).to eq
|
|
96
|
+
expect(streams_ctx4[2].send_window.length).to eq 65_535 - 3
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
let(:data_buffer5) do
|
|
100
100
|
data_buffer = DataBuffer.new
|
|
101
|
-
data_buffer
|
|
102
|
-
data_buffer
|
|
101
|
+
data_buffer.store(1, 'one')
|
|
102
|
+
data_buffer.store(2, 'two')
|
|
103
103
|
data_buffer
|
|
104
104
|
end
|
|
105
105
|
let(:send_window5) do
|
|
106
|
-
send_window = Window.new
|
|
107
|
-
send_window.consume!(
|
|
106
|
+
send_window = Window.new(65_535)
|
|
107
|
+
send_window.consume!(65_535)
|
|
108
108
|
send_window
|
|
109
109
|
end
|
|
110
110
|
let(:streams_ctx5) do
|
|
111
111
|
streams_ctx = StreamsContext.new
|
|
112
|
-
streams_ctx.new_context(1, do_nothing_proc)
|
|
113
|
-
streams_ctx.new_context(2, do_nothing_proc)
|
|
112
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
113
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
114
114
|
streams_ctx
|
|
115
115
|
end
|
|
116
116
|
it 'should take' do
|
|
117
|
-
expect(data_buffer5.take!(send_window5, streams_ctx5).length).to eq 0
|
|
117
|
+
expect(data_buffer5.take!(send_window5, streams_ctx5, 16_384).length).to eq 0
|
|
118
118
|
expect(send_window5.length).to eq 0
|
|
119
|
-
expect(streams_ctx5[1].send_window.length).to eq
|
|
120
|
-
expect(streams_ctx5[2].send_window.length).to eq
|
|
119
|
+
expect(streams_ctx5[1].send_window.length).to eq 65_535
|
|
120
|
+
expect(streams_ctx5[2].send_window.length).to eq 65_535
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
context 'has?' do
|
|
125
125
|
let(:data_buffer6) do
|
|
126
126
|
data_buffer = DataBuffer.new
|
|
127
|
-
data_buffer
|
|
127
|
+
data_buffer.store(1, 'one')
|
|
128
128
|
data_buffer
|
|
129
129
|
end
|
|
130
130
|
it 'should take' do
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require_relative 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe StreamsContext do
|
|
4
|
+
context 'close_all' do
|
|
5
|
+
let(:streams_ctx) do
|
|
6
|
+
streams_ctx = StreamsContext.new
|
|
7
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
8
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
9
|
+
streams_ctx
|
|
10
|
+
end
|
|
11
|
+
it 'should close' do
|
|
12
|
+
streams_ctx.close_all
|
|
13
|
+
expect { streams_ctx[1].tx << nil }.to raise_error Ractor::ClosedError
|
|
14
|
+
expect { streams_ctx[2].tx << nil }.to raise_error Ractor::ClosedError
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'close_all' do
|
|
19
|
+
let(:streams_ctx) do
|
|
20
|
+
streams_ctx = StreamsContext.new
|
|
21
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
22
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
23
|
+
streams_ctx
|
|
24
|
+
end
|
|
25
|
+
it 'should close' do
|
|
26
|
+
streams_ctx.close_all
|
|
27
|
+
expect { streams_ctx[1].tx << nil }.to raise_error Ractor::ClosedError
|
|
28
|
+
expect { streams_ctx[2].tx << nil }.to raise_error Ractor::ClosedError
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'remove_closed' do
|
|
33
|
+
let(:streams_ctx1) do
|
|
34
|
+
streams_ctx = StreamsContext.new
|
|
35
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
36
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
37
|
+
streams_ctx
|
|
38
|
+
end
|
|
39
|
+
let(:data_buffer1) do
|
|
40
|
+
DataBuffer.new
|
|
41
|
+
end
|
|
42
|
+
it 'should remove' do
|
|
43
|
+
streams_ctx1.remove_closed(data_buffer1)
|
|
44
|
+
expect(streams_ctx1.length).to eq 2
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
let(:streams_ctx2) do
|
|
48
|
+
streams_ctx = StreamsContext.new
|
|
49
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
50
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
51
|
+
streams_ctx[2].state.close
|
|
52
|
+
streams_ctx
|
|
53
|
+
end
|
|
54
|
+
let(:data_buffer2) do
|
|
55
|
+
DataBuffer.new
|
|
56
|
+
end
|
|
57
|
+
it 'should remove' do
|
|
58
|
+
streams_ctx2.remove_closed(data_buffer2)
|
|
59
|
+
expect(streams_ctx2.length).to eq 2 # remain stream_id
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
let(:streams_ctx3) do
|
|
63
|
+
streams_ctx = StreamsContext.new
|
|
64
|
+
streams_ctx.new_context(1, 65_535, 65_535, do_nothing_proc)
|
|
65
|
+
streams_ctx.new_context(2, 65_535, 65_535, do_nothing_proc)
|
|
66
|
+
streams_ctx[2].state.close
|
|
67
|
+
streams_ctx
|
|
68
|
+
end
|
|
69
|
+
let(:data_buffer3) do
|
|
70
|
+
data_buffer = DataBuffer.new
|
|
71
|
+
data_buffer.store(2, 'two')
|
|
72
|
+
data_buffer
|
|
73
|
+
end
|
|
74
|
+
it 'should remove' do
|
|
75
|
+
streams_ctx3.remove_closed(data_buffer3)
|
|
76
|
+
expect(streams_ctx3.length).to eq 2
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|