grpc_kit 0.1.7 → 0.1.8
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/TODO.md +1 -1
- data/grpc_kit.gemspec +1 -1
- data/lib/grpc_kit/session/client_session.rb +3 -1
- data/lib/grpc_kit/session/headers.rb +47 -50
- data/lib/grpc_kit/session/io.rb +4 -0
- data/lib/grpc_kit/session/recv_buffer.rb +41 -0
- data/lib/grpc_kit/session/send_buffer.rb +53 -0
- data/lib/grpc_kit/session/server_session.rb +17 -12
- data/lib/grpc_kit/session/stream.rb +4 -3
- data/lib/grpc_kit/stream/server_stream.rb +23 -9
- data/lib/grpc_kit/transport/client_transport.rb +15 -27
- data/lib/grpc_kit/transport/packable.rb +12 -20
- data/lib/grpc_kit/transport/server_transport.rb +23 -12
- data/lib/grpc_kit/version.rb +1 -1
- metadata +6 -6
- data/lib/grpc_kit/session/buffer.rb +0 -61
- data/lib/grpc_kit/transport/send_buffer.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7b605bf4f8cf8486b85fbb391296e0e9acb21ca00efc29850271e9890b6a386
|
4
|
+
data.tar.gz: cc8597e07c5e467c249dc78a4ad5f02fc811410039e7eadaecfe176ae9dc3b20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb29d063711fa507ff5d85a6bd9ef7e7fac86ffb4502947ab144feea453a01901ee9fc14c05e0a10a2a10d0b73fbfc1ee4e0dcc58b1c4ccf5ef9b6b974295548
|
7
|
+
data.tar.gz: 9e98bb7709c5bdc49683e57d9134877d8ec558feff9d1081a1f49e76afc47969172843f5b4669b8d84f74a826bb58a58372840f8011f82bd7a1bca3b2ec76e58
|
data/TODO.md
CHANGED
@@ -46,7 +46,7 @@
|
|
46
46
|
- [x] internal
|
47
47
|
- [ ] resouce exhausted (worker is exhausted)
|
48
48
|
- [x] duration parse in header
|
49
|
-
- [
|
49
|
+
- [x] send `grpc-status` along with header frame if possible
|
50
50
|
- need to support https://nghttp2.org/documentation/nghttp2_submit_response.html, data_prd is not NULL
|
51
51
|
- [x] unimplemented error
|
52
52
|
- [ ] goaway
|
data/grpc_kit.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
|
-
spec.add_dependency 'ds9', '~> 1.
|
25
|
+
spec.add_dependency 'ds9', '~> 1.3.0'
|
26
26
|
spec.add_dependency 'google-protobuf', '~> 3.6.1'
|
27
27
|
spec.add_dependency 'googleapis-common-protos-types', '~> 1.0.2'
|
28
28
|
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'ds9'
|
4
4
|
require 'forwardable'
|
5
5
|
require 'grpc_kit/session/stream'
|
6
|
+
require 'grpc_kit/session/send_buffer'
|
6
7
|
|
7
8
|
module GrpcKit
|
8
9
|
module Session
|
@@ -26,11 +27,12 @@ module GrpcKit
|
|
26
27
|
@stop = false
|
27
28
|
end
|
28
29
|
|
29
|
-
def send_request(
|
30
|
+
def send_request(headers)
|
30
31
|
if @draining
|
31
32
|
raise ConnectionClosing, "You can't send new request. becuase this connection will shuting down"
|
32
33
|
end
|
33
34
|
|
35
|
+
data = GrpcKit::Session::SendBuffer.new
|
34
36
|
stream_id = submit_request(headers, data).to_i
|
35
37
|
stream = GrpcKit::Session::Stream.new(stream_id: stream_id, send_data: data)
|
36
38
|
stream.stream_id = stream_id
|
@@ -4,66 +4,63 @@ require 'grpc_kit/grpc_time'
|
|
4
4
|
|
5
5
|
module GrpcKit
|
6
6
|
module Session
|
7
|
-
Headers
|
8
|
-
:metadata,
|
9
|
-
:path,
|
10
|
-
:grpc_encoding,
|
11
|
-
:grpc_status,
|
12
|
-
:status_message,
|
13
|
-
:timeout,
|
14
|
-
:method,
|
15
|
-
:http_status,
|
16
|
-
) do
|
17
|
-
|
7
|
+
class Headers
|
18
8
|
RESERVED_HEADERS = [
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'grpc-message-
|
22
|
-
'grpc-encoding',
|
23
|
-
'
|
24
|
-
'grpc-status',
|
25
|
-
'grpc-status-details-bin',
|
26
|
-
'grpc-accept-encoding',
|
27
|
-
'te'
|
9
|
+
':path', ':status', ':scheme',
|
10
|
+
'content-type', 'grpc-message-type', 'grpc-timeout',
|
11
|
+
'grpc-encoding', 'grpc-message', 'grpc-status',
|
12
|
+
'grpc-status-details-bin', 'grpc-accept-encoding', 'te',
|
13
|
+
':method'
|
28
14
|
].freeze
|
29
15
|
|
30
|
-
IGNORE_HEADERS = [':method', ':scheme'].freeze
|
31
|
-
|
32
16
|
METADATA_ACCEPTABLE_HEADER = %w[:authority user-agent].freeze
|
17
|
+
|
33
18
|
def initialize
|
34
|
-
|
19
|
+
@opts = {}
|
20
|
+
@metadata = {}
|
35
21
|
end
|
36
22
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
when 'grpc-encoding'
|
46
|
-
self.grpc_encoding = val
|
47
|
-
when 'grpc-status'
|
48
|
-
self.grpc_status = val
|
49
|
-
when 'grpc-timeout'
|
50
|
-
self.timeout = GrpcTime.new(val)
|
51
|
-
when 'grpc-message'
|
52
|
-
self.status_message = val
|
53
|
-
when 'grpc-status-details-bin'
|
54
|
-
# TODO
|
55
|
-
GrpcKit.logger.warn('grpc-status-details-bin is unsupported header now')
|
56
|
-
else
|
57
|
-
if IGNORE_HEADERS.include?(key)
|
58
|
-
return
|
23
|
+
def metadata
|
24
|
+
@metadata =
|
25
|
+
if @metadata.empty?
|
26
|
+
@opts.select do |key|
|
27
|
+
!key.start_with?(':', 'grpc-') && !RESERVED_HEADERS.include?(key)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
@metadata
|
59
31
|
end
|
32
|
+
end
|
60
33
|
|
61
|
-
|
62
|
-
|
63
|
-
|
34
|
+
def path
|
35
|
+
@opts[':path']
|
36
|
+
end
|
37
|
+
|
38
|
+
def grpc_status
|
39
|
+
@opts['grpc-status']
|
40
|
+
end
|
41
|
+
|
42
|
+
def grpc_encoding
|
43
|
+
@opts['grpc-encoding']
|
44
|
+
end
|
45
|
+
|
46
|
+
def content_type
|
47
|
+
@opts['content-type']
|
48
|
+
end
|
49
|
+
|
50
|
+
def status_message
|
51
|
+
@opts['grpc-message']
|
52
|
+
end
|
64
53
|
|
65
|
-
|
66
|
-
|
54
|
+
def timeout
|
55
|
+
@timeout ||= @opts['grpc-timeout'] && GrpcTime.new(@opts['grpc-timeout'])
|
56
|
+
end
|
57
|
+
|
58
|
+
def http_status
|
59
|
+
@opts[':status']
|
60
|
+
end
|
61
|
+
|
62
|
+
def add(key, val)
|
63
|
+
@opts[key] = val
|
67
64
|
end
|
68
65
|
end
|
69
66
|
end
|
data/lib/grpc_kit/session/io.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
module Session
|
5
|
+
class RecvBuffer
|
6
|
+
def initialize
|
7
|
+
@buffer = +''.b
|
8
|
+
@end = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(data)
|
12
|
+
@buffer << data
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(size = nil, last: false)
|
16
|
+
return nil if @buffer.empty?
|
17
|
+
|
18
|
+
end_read if last
|
19
|
+
|
20
|
+
if size.nil? || @buffer.bytesize < size
|
21
|
+
buf = @buffer
|
22
|
+
@buffer = ''.b
|
23
|
+
buf
|
24
|
+
else
|
25
|
+
@buffer.freeze
|
26
|
+
rbuf = @buffer.byteslice(0, size)
|
27
|
+
@buffer = @buffer.byteslice(size, @buffer.bytesize)
|
28
|
+
rbuf
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def end_read?
|
33
|
+
@end
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_read
|
37
|
+
@end = true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
module Session
|
5
|
+
class SendBuffer
|
6
|
+
def initialize
|
7
|
+
@buffer = ''.b
|
8
|
+
@end_write = false
|
9
|
+
@deferred_read = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(data, last: false)
|
13
|
+
end_write if last
|
14
|
+
@buffer << data
|
15
|
+
end
|
16
|
+
|
17
|
+
def need_resume?
|
18
|
+
@deferred_read
|
19
|
+
end
|
20
|
+
|
21
|
+
def end_write
|
22
|
+
@end_write = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def end_write?
|
26
|
+
@end_write
|
27
|
+
end
|
28
|
+
|
29
|
+
def read(size = nil)
|
30
|
+
if @buffer.empty?
|
31
|
+
if end_write?
|
32
|
+
@deferred_read = false
|
33
|
+
return nil # EOF
|
34
|
+
end
|
35
|
+
|
36
|
+
@deferred_read = true
|
37
|
+
return DS9::ERR_DEFERRED
|
38
|
+
end
|
39
|
+
|
40
|
+
if size.nil? || @buffer.bytesize < size
|
41
|
+
buf = @buffer
|
42
|
+
@buffer = ''.b
|
43
|
+
buf
|
44
|
+
else
|
45
|
+
@buffer.freeze
|
46
|
+
rbuf = @buffer.byteslice(0, size)
|
47
|
+
@buffer = @buffer.byteslice(size, @buffer.bytesize)
|
48
|
+
rbuf
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -6,6 +6,7 @@ require 'grpc_kit/session/stream'
|
|
6
6
|
require 'grpc_kit/session/drain_controller'
|
7
7
|
require 'grpc_kit/stream/server_stream'
|
8
8
|
require 'grpc_kit/transport/server_transport'
|
9
|
+
require 'grpc_kit/session/send_buffer'
|
9
10
|
|
10
11
|
module GrpcKit
|
11
12
|
module Session
|
@@ -32,7 +33,7 @@ module GrpcKit
|
|
32
33
|
loop do
|
33
34
|
invoke
|
34
35
|
|
35
|
-
if @streams.
|
36
|
+
if @streams.size == 0
|
36
37
|
unless @io.wait_readable
|
37
38
|
shutdown
|
38
39
|
break
|
@@ -63,11 +64,13 @@ module GrpcKit
|
|
63
64
|
@drain.call(self)
|
64
65
|
end
|
65
66
|
|
66
|
-
|
67
|
+
rs, ws = @io.select
|
68
|
+
|
69
|
+
if !rs.empty? && want_read?
|
67
70
|
do_read
|
68
71
|
end
|
69
72
|
|
70
|
-
if want_write?
|
73
|
+
if !ws.empty? && want_write?
|
71
74
|
send
|
72
75
|
end
|
73
76
|
|
@@ -122,7 +125,7 @@ module GrpcKit
|
|
122
125
|
|
123
126
|
stream = @streams[stream_id]
|
124
127
|
data = @streams[stream_id].pending_send_data.read(length)
|
125
|
-
if data.
|
128
|
+
if data.nil?
|
126
129
|
submit_trailer(stream_id, stream.trailer_data)
|
127
130
|
# trailer header
|
128
131
|
false
|
@@ -133,7 +136,7 @@ module GrpcKit
|
|
133
136
|
|
134
137
|
# nghttp2_session_callbacks_set_on_frame_recv_callback
|
135
138
|
def on_frame_recv(frame)
|
136
|
-
GrpcKit.logger.debug("on_frame_recv #{frame}")
|
139
|
+
# GrpcKit.logger.debug("on_frame_recv #{frame}") # Too many call
|
137
140
|
|
138
141
|
case frame
|
139
142
|
when DS9::Frames::Data
|
@@ -148,9 +151,8 @@ module GrpcKit
|
|
148
151
|
@inflights << stream
|
149
152
|
end
|
150
153
|
when DS9::Frames::Headers
|
151
|
-
stream = @streams[frame.stream_id]
|
152
|
-
|
153
154
|
if frame.end_stream?
|
155
|
+
stream = @streams[frame.stream_id]
|
154
156
|
stream.close_remote
|
155
157
|
end
|
156
158
|
when DS9::Frames::Ping
|
@@ -170,11 +172,11 @@ module GrpcKit
|
|
170
172
|
|
171
173
|
# nghttp2_session_callbacks_set_on_frame_send_callback
|
172
174
|
def on_frame_send(frame)
|
173
|
-
GrpcKit.logger.debug("on_frame_send #{frame}")
|
175
|
+
# GrpcKit.logger.debug("on_frame_send #{frame}") # Too many call
|
174
176
|
case frame
|
175
177
|
when DS9::Frames::Data, DS9::Frames::Headers
|
176
|
-
stream = @streams[frame.stream_id]
|
177
178
|
if frame.end_stream?
|
179
|
+
stream = @streams[frame.stream_id]
|
178
180
|
stream.close_local
|
179
181
|
end
|
180
182
|
end
|
@@ -197,12 +199,12 @@ module GrpcKit
|
|
197
199
|
raise "#{stream_id} is already existed"
|
198
200
|
end
|
199
201
|
|
200
|
-
@streams[stream_id] = GrpcKit::Session::Stream.new(stream_id: stream_id)
|
202
|
+
@streams[stream_id] = GrpcKit::Session::Stream.new(stream_id: stream_id, send_data: GrpcKit::Session::SendBuffer.new)
|
201
203
|
end
|
202
204
|
|
203
205
|
# nghttp2_session_callbacks_set_on_header_callback
|
204
206
|
def on_header(name, value, frame, _flags)
|
205
|
-
GrpcKit.logger.debug("#{name} => #{value}")
|
207
|
+
# GrpcKit.logger.debug("#{name} => #{value}") # Too many call
|
206
208
|
stream = @streams[frame.stream_id]
|
207
209
|
stream.add_header(name, value)
|
208
210
|
end
|
@@ -214,7 +216,10 @@ module GrpcKit
|
|
214
216
|
|
215
217
|
# nghttp2_session_callbacks_set_on_stream_close_callback
|
216
218
|
def on_stream_close(stream_id, error_code)
|
217
|
-
|
219
|
+
if error_code != DS9::NO_ERROR
|
220
|
+
GrpcKit.logger.debug("on_stream_close stream_id=#{stream_id}, error_code=#{error_code}")
|
221
|
+
end
|
222
|
+
|
218
223
|
stream = @streams.delete(stream_id)
|
219
224
|
stream.close if stream
|
220
225
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
-
require 'grpc_kit/session/buffer'
|
5
4
|
require 'grpc_kit/session/headers'
|
6
5
|
require 'grpc_kit/session/stream_status'
|
6
|
+
require 'grpc_kit/session/recv_buffer'
|
7
|
+
require 'grpc_kit/session/send_buffer'
|
7
8
|
|
8
9
|
module GrpcKit
|
9
10
|
module Session
|
@@ -21,8 +22,8 @@ module GrpcKit
|
|
21
22
|
@stream_id = stream_id
|
22
23
|
@end_read_stream = false
|
23
24
|
@headers = GrpcKit::Session::Headers.new
|
24
|
-
@pending_send_data = send_data || GrpcKit::Session::
|
25
|
-
@pending_recv_data = recv_data || GrpcKit::Session::
|
25
|
+
@pending_send_data = send_data || GrpcKit::Session::SendBuffer.new
|
26
|
+
@pending_recv_data = recv_data || GrpcKit::Session::RecvBuffer.new
|
26
27
|
|
27
28
|
@inflight = false
|
28
29
|
@trailer_data = {}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grpc_kit/
|
3
|
+
require 'grpc_kit/errors'
|
4
4
|
|
5
5
|
module GrpcKit
|
6
6
|
module Stream
|
@@ -61,8 +61,6 @@ module GrpcKit
|
|
61
61
|
raise 'compress option is unsupported'
|
62
62
|
end
|
63
63
|
|
64
|
-
raise StopIteration if buf.nil?
|
65
|
-
|
66
64
|
begin
|
67
65
|
protobuf.decode(buf)
|
68
66
|
rescue ArgumentError => e
|
@@ -70,19 +68,35 @@ module GrpcKit
|
|
70
68
|
end
|
71
69
|
end
|
72
70
|
|
73
|
-
def each
|
74
|
-
loop { yield(
|
71
|
+
def each(protobuf)
|
72
|
+
loop { yield(recv_msg(protobuf)) }
|
75
73
|
end
|
76
74
|
|
77
75
|
def send_status(data: nil, status: GrpcKit::StatusCodes::OK, msg: nil, metadata: {})
|
76
|
+
t = build_trailers(status, msg, metadata)
|
78
77
|
@transport.write_data(data, last: true) if data
|
79
|
-
write_trailers(status, msg, metadata)
|
80
78
|
|
81
|
-
|
79
|
+
@transport.end_write
|
80
|
+
if @started
|
81
|
+
@transport.write_trailers(t)
|
82
|
+
elsif data
|
83
|
+
@transport.write_trailers(t)
|
84
|
+
start_response
|
85
|
+
else
|
86
|
+
send_headers(trailers: t)
|
87
|
+
end
|
82
88
|
end
|
83
89
|
|
84
90
|
private
|
85
91
|
|
92
|
+
def send_headers(trailers: {})
|
93
|
+
h = { ':status' => '200', 'content-type' => 'application/grpc' }
|
94
|
+
h['accept-encoding'] = 'identity'
|
95
|
+
|
96
|
+
@transport.submit_headers(h.merge(trailers))
|
97
|
+
@started = true
|
98
|
+
end
|
99
|
+
|
86
100
|
def start_response(data = nil, metadata: {})
|
87
101
|
h = { ':status' => '200', 'content-type' => 'application/grpc' }
|
88
102
|
h['accept-encoding'] = 'identity'
|
@@ -92,13 +106,13 @@ module GrpcKit
|
|
92
106
|
@started = true
|
93
107
|
end
|
94
108
|
|
95
|
-
def
|
109
|
+
def build_trailers(status, msg, metadata)
|
96
110
|
trailers = { 'grpc-status' => status.to_s }
|
97
111
|
if msg
|
98
112
|
trailers['grpc-message'] = msg
|
99
113
|
end
|
100
114
|
|
101
|
-
|
115
|
+
trailers.merge(metadata)
|
102
116
|
end
|
103
117
|
end
|
104
118
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'grpc_kit/transport/packable'
|
4
|
-
require 'grpc_kit/transport/send_buffer'
|
5
4
|
|
6
5
|
module GrpcKit
|
7
6
|
module Transport
|
@@ -12,42 +11,29 @@ module GrpcKit
|
|
12
11
|
def initialize(session)
|
13
12
|
@session = session
|
14
13
|
@stream = nil # set later
|
15
|
-
@deferred = false
|
16
14
|
end
|
17
15
|
|
18
16
|
def start_request(data, header, last: false)
|
19
|
-
@stream = @session.send_request(
|
17
|
+
@stream = @session.send_request(header)
|
20
18
|
write_data(data, last: last)
|
21
19
|
end
|
22
20
|
|
23
21
|
def close_and_flush
|
24
|
-
resume_if_need
|
25
|
-
|
26
22
|
@stream.end_write
|
23
|
+
send_data
|
24
|
+
|
27
25
|
@session.start(@stream.stream_id)
|
28
26
|
@stream.end_read
|
29
27
|
@deferred = false
|
30
28
|
end
|
31
29
|
|
32
|
-
def each
|
33
|
-
loop do
|
34
|
-
data = recv
|
35
|
-
return if data.nil?
|
36
|
-
|
37
|
-
yield(data)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
30
|
def write_data(buf, last: false)
|
42
|
-
resume_if_need
|
43
|
-
|
44
31
|
write(@stream.pending_send_data, pack(buf), last: last)
|
45
|
-
|
46
|
-
@deferred = true unless last
|
32
|
+
send_data
|
47
33
|
end
|
48
34
|
|
49
35
|
def read_data(last: false)
|
50
|
-
unpack(
|
36
|
+
unpack(recv_data(last: last))
|
51
37
|
end
|
52
38
|
|
53
39
|
def recv_headers
|
@@ -57,12 +43,6 @@ module GrpcKit
|
|
57
43
|
|
58
44
|
private
|
59
45
|
|
60
|
-
def resume_if_need
|
61
|
-
if !@stream.end_write? && @deferred
|
62
|
-
@session.resume_data(@stream.stream_id)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
46
|
def wait_close
|
67
47
|
# XXX: wait until half close (remote) to get grpc-status
|
68
48
|
until @stream.close_remote?
|
@@ -74,10 +54,10 @@ module GrpcKit
|
|
74
54
|
stream.write(buf, last: last)
|
75
55
|
end
|
76
56
|
|
77
|
-
def
|
57
|
+
def recv_data(last: false)
|
78
58
|
loop do
|
79
59
|
data = @stream.read_recv_data(last: last)
|
80
|
-
return data unless data.
|
60
|
+
return data unless data.nil?
|
81
61
|
|
82
62
|
if @stream.close_remote?
|
83
63
|
# it do not receive data which we need, it may receive invalid grpc-status
|
@@ -91,6 +71,14 @@ module GrpcKit
|
|
91
71
|
@session.run_once
|
92
72
|
end
|
93
73
|
end
|
74
|
+
|
75
|
+
def send_data
|
76
|
+
if @stream.pending_send_data.need_resume?
|
77
|
+
@session.resume_data(@stream.stream_id)
|
78
|
+
end
|
79
|
+
|
80
|
+
@session.run_once
|
81
|
+
end
|
94
82
|
end
|
95
83
|
end
|
96
84
|
end
|
@@ -12,15 +12,9 @@ module GrpcKit
|
|
12
12
|
|
13
13
|
# @params data [String]
|
14
14
|
def unpack(data)
|
15
|
-
if data
|
16
|
-
unpacker.feed(data)
|
17
|
-
end
|
18
|
-
|
19
|
-
if unpacker.readable?
|
20
|
-
return unpacker.read
|
21
|
-
end
|
15
|
+
unpacker.feed(data) if data
|
22
16
|
|
23
|
-
|
17
|
+
unpacker.read
|
24
18
|
end
|
25
19
|
|
26
20
|
def unpacker
|
@@ -32,27 +26,25 @@ module GrpcKit
|
|
32
26
|
METADATA_SIZE = 5
|
33
27
|
|
34
28
|
def initialize
|
35
|
-
@
|
36
|
-
@data = nil
|
29
|
+
@data = +''.b
|
37
30
|
end
|
38
31
|
|
39
|
-
def
|
40
|
-
|
32
|
+
def data_exist?
|
33
|
+
!@data.empty?
|
41
34
|
end
|
42
35
|
|
43
36
|
def feed(data)
|
44
|
-
|
45
|
-
@data << data
|
46
|
-
else
|
47
|
-
@data = data
|
48
|
-
end
|
37
|
+
@data << data
|
49
38
|
end
|
50
39
|
|
51
40
|
def read
|
52
|
-
|
41
|
+
return nil if @data.empty?
|
42
|
+
|
43
|
+
d = @data.freeze
|
44
|
+
metadata = d.byteslice(0, METADATA_SIZE)
|
53
45
|
c, size = metadata.unpack('CN')
|
54
|
-
|
55
|
-
data = @data.
|
46
|
+
data = @data.byteslice(METADATA_SIZE, size)
|
47
|
+
@data = @data.byteslice(METADATA_SIZE + size, @data.bytesize)
|
56
48
|
[c != 0, size, data]
|
57
49
|
end
|
58
50
|
end
|
@@ -14,29 +14,30 @@ module GrpcKit
|
|
14
14
|
@stream = stream
|
15
15
|
end
|
16
16
|
|
17
|
-
def each
|
18
|
-
loop do
|
19
|
-
data = recv
|
20
|
-
return if data.nil?
|
21
|
-
|
22
|
-
yield(data)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
17
|
def start_response(headers)
|
27
18
|
@session.submit_response(@stream.stream_id, headers)
|
19
|
+
send_data
|
20
|
+
end
|
21
|
+
|
22
|
+
def submit_headers(headers)
|
23
|
+
@session.submit_headers(@stream.stream_id, headers)
|
28
24
|
end
|
29
25
|
|
30
26
|
def write_data(buf, last: false)
|
31
27
|
@stream.write_send_data(pack(buf), last: last)
|
28
|
+
send_data(last: last)
|
32
29
|
end
|
33
30
|
|
34
31
|
def read_data(last: false)
|
35
|
-
unpack(
|
32
|
+
unpack(recv_data(last: last))
|
36
33
|
end
|
37
34
|
|
38
35
|
def write_trailers(trailer)
|
39
36
|
@stream.write_trailers_data(trailer)
|
37
|
+
send_data(last: true)
|
38
|
+
end
|
39
|
+
|
40
|
+
def end_write
|
40
41
|
@stream.end_write
|
41
42
|
end
|
42
43
|
|
@@ -46,10 +47,10 @@ module GrpcKit
|
|
46
47
|
|
47
48
|
private
|
48
49
|
|
49
|
-
def
|
50
|
+
def recv_data(last: false)
|
50
51
|
loop do
|
51
52
|
data = @stream.read_recv_data(last: last)
|
52
|
-
return data unless data.
|
53
|
+
return data unless data.nil?
|
53
54
|
|
54
55
|
if @stream.close_remote?
|
55
56
|
# it do not receive data which we need, it may receive invalid grpc-status
|
@@ -63,6 +64,16 @@ module GrpcKit
|
|
63
64
|
@session.run_once
|
64
65
|
end
|
65
66
|
end
|
67
|
+
|
68
|
+
def send_data(last: false)
|
69
|
+
if @stream.pending_send_data.need_resume?
|
70
|
+
@session.resume_data(@stream.stream_id)
|
71
|
+
end
|
72
|
+
|
73
|
+
unless last
|
74
|
+
@session.run_once
|
75
|
+
end
|
76
|
+
end
|
66
77
|
end
|
67
78
|
end
|
68
79
|
end
|
data/lib/grpc_kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ganmacs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ds9
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: google-protobuf
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,11 +207,12 @@ files:
|
|
207
207
|
- lib/grpc_kit/rpcs/server_request_response.rb
|
208
208
|
- lib/grpc_kit/rpcs/server_server_streamer.rb
|
209
209
|
- lib/grpc_kit/server.rb
|
210
|
-
- lib/grpc_kit/session/buffer.rb
|
211
210
|
- lib/grpc_kit/session/client_session.rb
|
212
211
|
- lib/grpc_kit/session/drain_controller.rb
|
213
212
|
- lib/grpc_kit/session/headers.rb
|
214
213
|
- lib/grpc_kit/session/io.rb
|
214
|
+
- lib/grpc_kit/session/recv_buffer.rb
|
215
|
+
- lib/grpc_kit/session/send_buffer.rb
|
215
216
|
- lib/grpc_kit/session/server_session.rb
|
216
217
|
- lib/grpc_kit/session/stream.rb
|
217
218
|
- lib/grpc_kit/session/stream_status.rb
|
@@ -220,7 +221,6 @@ files:
|
|
220
221
|
- lib/grpc_kit/stream/server_stream.rb
|
221
222
|
- lib/grpc_kit/transport/client_transport.rb
|
222
223
|
- lib/grpc_kit/transport/packable.rb
|
223
|
-
- lib/grpc_kit/transport/send_buffer.rb
|
224
224
|
- lib/grpc_kit/transport/server_transport.rb
|
225
225
|
- lib/grpc_kit/version.rb
|
226
226
|
homepage: https://github.com/ganmacs/grpc_kit
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GrpcKit
|
4
|
-
module Session
|
5
|
-
class Buffer
|
6
|
-
attr_accessor :finish
|
7
|
-
|
8
|
-
def initialize(buffer: nil)
|
9
|
-
@buffer = buffer
|
10
|
-
@end_read = false
|
11
|
-
@end_write = false
|
12
|
-
@finish = false
|
13
|
-
end
|
14
|
-
|
15
|
-
def write(data, last: false)
|
16
|
-
return 0 if data.empty?
|
17
|
-
|
18
|
-
end_write if last
|
19
|
-
|
20
|
-
if @buffer
|
21
|
-
@buffer << data
|
22
|
-
else
|
23
|
-
@buffer = data.dup
|
24
|
-
end
|
25
|
-
|
26
|
-
data.bytesize
|
27
|
-
end
|
28
|
-
|
29
|
-
def read(len = nil, last: false)
|
30
|
-
if @buffer.nil? || @buffer.empty?
|
31
|
-
return ''
|
32
|
-
end
|
33
|
-
|
34
|
-
end_read if last
|
35
|
-
|
36
|
-
# TODO: more efficient code
|
37
|
-
if len
|
38
|
-
@buffer.slice!(0...len)
|
39
|
-
else
|
40
|
-
@buffer.slice!(0..-1)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def end_read?
|
45
|
-
@end_read
|
46
|
-
end
|
47
|
-
|
48
|
-
def end_write?
|
49
|
-
@end_write
|
50
|
-
end
|
51
|
-
|
52
|
-
def end_read
|
53
|
-
@end_read = true
|
54
|
-
end
|
55
|
-
|
56
|
-
def end_write
|
57
|
-
@end_write = true
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GrpcKit
|
4
|
-
module Transport
|
5
|
-
class SendBuffer
|
6
|
-
def initialize
|
7
|
-
@buffer = nil
|
8
|
-
@end_write = false
|
9
|
-
end
|
10
|
-
|
11
|
-
def write(data, last: false)
|
12
|
-
end_write if last
|
13
|
-
|
14
|
-
if @buffer
|
15
|
-
@buffer << data
|
16
|
-
else
|
17
|
-
@buffer = data
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def end_write
|
22
|
-
@end_write = true
|
23
|
-
end
|
24
|
-
|
25
|
-
def end_write?
|
26
|
-
@end_write
|
27
|
-
end
|
28
|
-
|
29
|
-
def read(size)
|
30
|
-
if @buffer.nil?
|
31
|
-
return false
|
32
|
-
end
|
33
|
-
|
34
|
-
data = @buffer.slice!(0, size)
|
35
|
-
if !data.empty?
|
36
|
-
data
|
37
|
-
elsif end_write?
|
38
|
-
nil # EOF
|
39
|
-
else
|
40
|
-
false # deferred
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|