grpc_kit 0.1.2 → 0.1.3
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/.travis.yml +42 -3
- data/README.md +4 -1
- data/TODO.md +64 -0
- data/bin/nghttp2 +11 -0
- data/grpc_kit.gemspec +1 -1
- data/lib/grpc_kit/errors.rb +54 -15
- data/lib/grpc_kit/grpc/dsl.rb +1 -1
- data/lib/grpc_kit/interceptors/client_streamer.rb +5 -5
- data/lib/grpc_kit/interceptors/server_streamer.rb +5 -5
- data/lib/grpc_kit/interceptors/streaming.rb +8 -8
- data/lib/grpc_kit/rpcs/client_streamer.rb +3 -3
- data/lib/grpc_kit/rpcs/error.rb +23 -0
- data/lib/grpc_kit/rpcs/request_response.rb +17 -3
- data/lib/grpc_kit/rpcs/server_streamer.rb +5 -5
- data/lib/grpc_kit/rpcs.rb +1 -0
- data/lib/grpc_kit/server.rb +4 -2
- data/lib/grpc_kit/session/buffer.rb +9 -6
- data/lib/grpc_kit/session/client.rb +11 -8
- data/lib/grpc_kit/session/duration.rb +1 -0
- data/lib/grpc_kit/session/headers.rb +3 -4
- data/lib/grpc_kit/session/io.rb +7 -16
- data/lib/grpc_kit/session/server.rb +10 -10
- data/lib/grpc_kit/session/stream.rb +15 -26
- data/lib/grpc_kit/session/stream_status.rb +56 -0
- data/lib/grpc_kit/status_codes.rb +39 -18
- data/lib/grpc_kit/stream.rb +65 -16
- data/lib/grpc_kit/streams/client.rb +33 -7
- data/lib/grpc_kit/streams/packable.rb +2 -1
- data/lib/grpc_kit/streams/server.rb +29 -11
- data/lib/grpc_kit/version.rb +1 -1
- metadata +10 -7
- data/lib/grpc_kit/streams/stream.rb +0 -58
data/lib/grpc_kit/session/io.rb
CHANGED
@@ -27,23 +27,14 @@ module GrpcKit
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def send_event(data)
|
30
|
-
|
31
|
-
size = remain
|
32
|
-
while remain > 0
|
33
|
-
begin
|
34
|
-
remain -= @io.syswrite(data)
|
35
|
-
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
36
|
-
unless IO.select(nil, [io], nil, 1)
|
37
|
-
raise 'timeout writing data'
|
38
|
-
end
|
39
|
-
rescue IOError => e
|
40
|
-
raise IOError, e # TODO
|
41
|
-
end
|
42
|
-
|
43
|
-
data = data.byteslice(remain..-1)
|
44
|
-
end
|
30
|
+
return 0 if data.empty?
|
45
31
|
|
46
|
-
|
32
|
+
bytes = @io.write_nonblock(data, exception: false)
|
33
|
+
if bytes == :wait_writable
|
34
|
+
DS9::ERR_WOULDBLOCK
|
35
|
+
else
|
36
|
+
bytes
|
37
|
+
end
|
47
38
|
end
|
48
39
|
|
49
40
|
def wait_readable
|
@@ -36,7 +36,8 @@ module GrpcKit
|
|
36
36
|
|
37
37
|
run_once
|
38
38
|
end
|
39
|
-
rescue Errno::ECONNRESET, IOError
|
39
|
+
rescue Errno::ECONNRESET, IOError => e
|
40
|
+
GrpcKit.logger.debug(e.message)
|
40
41
|
finish
|
41
42
|
end
|
42
43
|
|
@@ -92,10 +93,9 @@ module GrpcKit
|
|
92
93
|
stream = @streams[stream_id]
|
93
94
|
data = @streams[stream_id].pending_send_data.read(length)
|
94
95
|
if data.empty? && stream.end_write?
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
false # means EOF and END_STREAM
|
96
|
+
submit_trailer(stream_id, stream.trailer_data)
|
97
|
+
# trailer header
|
98
|
+
false
|
99
99
|
else
|
100
100
|
data
|
101
101
|
end
|
@@ -107,11 +107,10 @@ module GrpcKit
|
|
107
107
|
|
108
108
|
case frame
|
109
109
|
when DS9::Frames::Data
|
110
|
-
|
111
110
|
stream = @streams[frame.stream_id]
|
112
111
|
|
113
112
|
if frame.end_stream?
|
114
|
-
stream.
|
113
|
+
stream.close_remote
|
115
114
|
end
|
116
115
|
|
117
116
|
unless stream.inflight
|
@@ -122,7 +121,7 @@ module GrpcKit
|
|
122
121
|
stream = @streams[frame.stream_id]
|
123
122
|
|
124
123
|
if frame.end_stream?
|
125
|
-
stream.
|
124
|
+
stream.close_remote
|
126
125
|
end
|
127
126
|
|
128
127
|
# when DS9::Frames::Goaway
|
@@ -139,7 +138,7 @@ module GrpcKit
|
|
139
138
|
when DS9::Frames::Data, DS9::Frames::Headers
|
140
139
|
stream = @streams[frame.stream_id]
|
141
140
|
if frame.end_stream?
|
142
|
-
stream.
|
141
|
+
stream.close_local
|
143
142
|
end
|
144
143
|
end
|
145
144
|
|
@@ -166,6 +165,7 @@ module GrpcKit
|
|
166
165
|
|
167
166
|
# nghttp2_session_callbacks_set_on_header_callback
|
168
167
|
def on_header(name, value, frame, _flags)
|
168
|
+
GrpcKit.logger.debug("#{name} => #{value}")
|
169
169
|
stream = @streams[frame.stream_id]
|
170
170
|
stream.add_header(name, value)
|
171
171
|
end
|
@@ -181,7 +181,7 @@ module GrpcKit
|
|
181
181
|
stream = @streams.delete(stream_id)
|
182
182
|
return unless stream
|
183
183
|
|
184
|
-
stream.
|
184
|
+
stream.close
|
185
185
|
end
|
186
186
|
|
187
187
|
# nghttp2_session_callbacks_set_on_data_chunk_recv_callback
|
@@ -3,28 +3,34 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'grpc_kit/session/buffer'
|
5
5
|
require 'grpc_kit/session/headers'
|
6
|
+
require 'grpc_kit/session/stream_status'
|
6
7
|
|
7
8
|
module GrpcKit
|
8
9
|
module Session
|
9
10
|
class Stream
|
10
11
|
extend Forwardable
|
11
12
|
|
12
|
-
delegate end_write
|
13
|
-
delegate end_read
|
13
|
+
delegate %i[end_write end_write?] => :@pending_send_data
|
14
|
+
delegate %i[end_read end_read?] => :@pending_recv_data
|
15
|
+
delegate %i[close close_remote close_local close? close_remote? close_local?] => :@status
|
14
16
|
|
15
|
-
attr_reader :headers, :pending_send_data, :pending_recv_data
|
16
|
-
attr_accessor :
|
17
|
+
attr_reader :headers, :pending_send_data, :pending_recv_data, :trailer_data, :status
|
18
|
+
attr_accessor :inflight, :stream_id
|
17
19
|
|
18
|
-
def initialize(stream_id:, send_data:
|
20
|
+
def initialize(stream_id:, send_data: nil, recv_data: nil)
|
19
21
|
@stream_id = stream_id
|
20
22
|
@end_read_stream = false
|
21
23
|
@headers = GrpcKit::Session::Headers.new
|
22
|
-
@pending_send_data = send_data
|
23
|
-
@pending_recv_data = GrpcKit::Session::Buffer.new
|
24
|
+
@pending_send_data = send_data || GrpcKit::Session::Buffer.new
|
25
|
+
@pending_recv_data = recv_data || GrpcKit::Session::Buffer.new
|
24
26
|
|
25
|
-
@local_end_stream = false
|
26
|
-
@remote_end_stream = false
|
27
27
|
@inflight = false
|
28
|
+
@trailer_data = {}
|
29
|
+
@status = GrpcKit::Session::StreamStatus.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_trailers_data(tariler)
|
33
|
+
@trailer_data = tariler
|
28
34
|
end
|
29
35
|
|
30
36
|
def write_send_data(data, last: false)
|
@@ -35,23 +41,6 @@ module GrpcKit
|
|
35
41
|
@pending_recv_data.read(last: last)
|
36
42
|
end
|
37
43
|
|
38
|
-
def end_write?
|
39
|
-
@local_end_stream || @pending_send_data.end_write?
|
40
|
-
end
|
41
|
-
|
42
|
-
def end_read?
|
43
|
-
@remote_end_stream || @pending_recv_data.end_read?
|
44
|
-
end
|
45
|
-
|
46
|
-
def end_stream?
|
47
|
-
end_read? && end_write?
|
48
|
-
end
|
49
|
-
|
50
|
-
def end_stream
|
51
|
-
end_read
|
52
|
-
end_write
|
53
|
-
end
|
54
|
-
|
55
44
|
def add_header(name, value)
|
56
45
|
@headers.add(name, value)
|
57
46
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
module Session
|
5
|
+
class StreamStatus
|
6
|
+
OPEN = 0
|
7
|
+
CLOSE = 1
|
8
|
+
HALF_CLOSE_REMOTE = 2
|
9
|
+
HALF_CLOSE_LOCAL = 3
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@status = OPEN
|
13
|
+
end
|
14
|
+
|
15
|
+
def close_local
|
16
|
+
if @status == OPEN
|
17
|
+
@status = HALF_CLOSE_LOCAL
|
18
|
+
elsif @status == HALF_CLOSE_REMOTE
|
19
|
+
@status = CLOSE
|
20
|
+
elsif @status == HALF_CLOSE_LOCAL
|
21
|
+
# nothing
|
22
|
+
else
|
23
|
+
raise 'stream is already closed'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def close_remote
|
28
|
+
if @status == OPEN
|
29
|
+
@status = HALF_CLOSE_REMOTE
|
30
|
+
elsif @status == HALF_CLOSE_LOCAL
|
31
|
+
@status = CLOSE
|
32
|
+
elsif @status == HALF_CLOSE_REMOTE
|
33
|
+
# nothing
|
34
|
+
else
|
35
|
+
raise 'stream is already closed'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def close
|
40
|
+
@status = CLOSE
|
41
|
+
end
|
42
|
+
|
43
|
+
def close_local?
|
44
|
+
(@status == HALF_CLOSE_LOCAL) || close?
|
45
|
+
end
|
46
|
+
|
47
|
+
def close_remote?
|
48
|
+
(@status == HALF_CLOSE_REMOTE) || close?
|
49
|
+
end
|
50
|
+
|
51
|
+
def close?
|
52
|
+
@status == CLOSE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -2,23 +2,44 @@
|
|
2
2
|
|
3
3
|
module GrpcKit
|
4
4
|
module StatusCodes
|
5
|
-
OK = 0
|
6
|
-
CANCELLED = 1
|
7
|
-
UNKNOWN = 2
|
8
|
-
INVALID_ARGUMENT = 3
|
9
|
-
DEADLINE_EXCEEDED = 4
|
10
|
-
NOT_FOUND = 5
|
11
|
-
ALREADY_EXISTS = 6
|
12
|
-
PERMISSION_DENIED = 7
|
13
|
-
RESOURCE_EXHAUSTED = 8
|
14
|
-
FAILED_PRECONDITION = 9
|
15
|
-
ABORTED = 10
|
16
|
-
OUT_OF_RANGE = 11
|
17
|
-
UNIMPLEMENTED = 12
|
18
|
-
INTERNAL = 13
|
19
|
-
UNAVAILABLE = 14
|
20
|
-
DATA_LOSS = 15
|
21
|
-
UNAUTHENTICATED = 16
|
22
|
-
DO_NOT_USE = -1
|
5
|
+
OK = '0'
|
6
|
+
CANCELLED = '1'
|
7
|
+
UNKNOWN = '2'
|
8
|
+
INVALID_ARGUMENT = '3'
|
9
|
+
DEADLINE_EXCEEDED = '4'
|
10
|
+
NOT_FOUND = '5'
|
11
|
+
ALREADY_EXISTS = '6'
|
12
|
+
PERMISSION_DENIED = '7'
|
13
|
+
RESOURCE_EXHAUSTED = '8'
|
14
|
+
FAILED_PRECONDITION = '9'
|
15
|
+
ABORTED = '10'
|
16
|
+
OUT_OF_RANGE = '11'
|
17
|
+
UNIMPLEMENTED = '12'
|
18
|
+
INTERNAL = '13'
|
19
|
+
UNAVAILABLE = '14'
|
20
|
+
DATA_LOSS = '15'
|
21
|
+
UNAUTHENTICATED = '16'
|
22
|
+
DO_NOT_USE = '-1'
|
23
|
+
|
24
|
+
CODE_NAME = {
|
25
|
+
OK => 'OK',
|
26
|
+
CANCELLED => 'CANCELLED',
|
27
|
+
UNKNOWN => 'UNKNOWN',
|
28
|
+
INVALID_ARGUMENT => 'INVALID_ARGUMENT',
|
29
|
+
DEADLINE_EXCEEDED => 'DEADLINE_EXCEEDED',
|
30
|
+
NOT_FOUND => 'NOT_FOUND',
|
31
|
+
ALREADY_EXISTS => 'ALREADY_EXISTS',
|
32
|
+
PERMISSION_DENIED => 'PERMISSION_DENIED',
|
33
|
+
RESOURCE_EXHAUSTED => 'RESOURCE_EXHAUSTED',
|
34
|
+
FAILED_PRECONDITION => 'FAILED_PRECONDITION',
|
35
|
+
ABORTED => 'ABORTED',
|
36
|
+
OUT_OF_RANGE => 'OUT_OF_RANGE',
|
37
|
+
UNIMPLEMENTED => 'UNIMPLEMENTED',
|
38
|
+
INTERNAL => 'INTERNAL',
|
39
|
+
UNAVAILABLE => 'UNAVAILABLE',
|
40
|
+
DATA_LOSS => 'DATA_LOSS',
|
41
|
+
UNAUTHENTICATED => 'UNAUTHENTICATED',
|
42
|
+
DO_NOT_USE => 'DO_NOT_USE',
|
43
|
+
}.freeze
|
23
44
|
end
|
24
45
|
end
|
data/lib/grpc_kit/stream.rb
CHANGED
@@ -9,7 +9,7 @@ module GrpcKit
|
|
9
9
|
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
delegate %i[stream_id end_write end_read end_write? end_read?] => :@stream
|
12
|
+
delegate %i[stream_id end_write end_read end_write? end_read? close_remote? headers] => :@stream
|
13
13
|
|
14
14
|
# @params protobuf [GrpcKit::Protobuffer]
|
15
15
|
# @params session [GrpcKit::Session::Server|GrpcKit::Session::Client]
|
@@ -21,20 +21,34 @@ module GrpcKit
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def each
|
24
|
-
loop
|
24
|
+
loop do
|
25
|
+
data = recv
|
26
|
+
return if data.nil?
|
27
|
+
|
28
|
+
yield(data)
|
29
|
+
end
|
25
30
|
end
|
26
31
|
|
27
|
-
def send(data, last: false)
|
28
|
-
|
29
|
-
|
32
|
+
def send(data, last: false, limit_size: nil)
|
33
|
+
b =
|
34
|
+
begin
|
35
|
+
@protobuf.encode(data)
|
36
|
+
rescue ArgumentError => e
|
37
|
+
raise GrpcKit::Errors::Internal, "Error while encoding: #{e}"
|
38
|
+
end
|
39
|
+
|
40
|
+
req = pack(b)
|
41
|
+
if limit_size && req.bytesize > limit_size
|
42
|
+
raise GrpcKit::Errors::ResourceExhausted, "Sending message is too large: send=#{req.bytesize}, max=#{limit_size}"
|
43
|
+
end
|
44
|
+
|
45
|
+
@stream.write_send_data(req, last: last)
|
30
46
|
end
|
31
47
|
|
32
|
-
def recv(last: false)
|
48
|
+
def recv(last: false, limit_size: nil)
|
33
49
|
data = unpack(read(last: last))
|
34
50
|
|
35
|
-
unless data
|
36
|
-
raise StopIteration
|
37
|
-
end
|
51
|
+
return nil unless data
|
38
52
|
|
39
53
|
compressed, size, buf = *data
|
40
54
|
|
@@ -42,11 +56,45 @@ module GrpcKit
|
|
42
56
|
raise "inconsistent data: #{buf}"
|
43
57
|
end
|
44
58
|
|
59
|
+
if limit_size && size > limit_size
|
60
|
+
raise GrpcKit::Errors::ResourceExhausted, "Receving message is too large: recevied=#{size}, max=#{limit_size}"
|
61
|
+
end
|
62
|
+
|
45
63
|
if compressed
|
46
64
|
raise 'compress option is unsupported'
|
47
65
|
end
|
48
66
|
|
49
|
-
|
67
|
+
begin
|
68
|
+
@protobuf.decode(buf)
|
69
|
+
rescue ArgumentError => e
|
70
|
+
raise GrpcKit::Errors::Internal, "Error while decoding #{e}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def send_trailer(status: GrpcKit::StatusCodes::OK, msg: nil, metadata: {})
|
75
|
+
trailer = metadata.dup
|
76
|
+
trailer['grpc-status'] = status.to_s
|
77
|
+
if msg
|
78
|
+
trailer['grpc-message'] = msg
|
79
|
+
end
|
80
|
+
|
81
|
+
@stream.write_trailers_data(trailer)
|
82
|
+
@stream.end_write
|
83
|
+
end
|
84
|
+
|
85
|
+
# TODO: use actual data
|
86
|
+
def submit_response(_header = nil, piggyback_trailer: false)
|
87
|
+
headers = { ':status' => '200', 'content-type' => 'application/grpc' }
|
88
|
+
|
89
|
+
# ds9 does not support nthttp2_submit_{response|request} without body
|
90
|
+
# if piggyback_trailer
|
91
|
+
# headers.merge!(@stream.trailer_data)
|
92
|
+
# @stream.need_trailer = false
|
93
|
+
# else
|
94
|
+
headers['accept-encoding'] = 'identity'
|
95
|
+
# end
|
96
|
+
|
97
|
+
@session.submit_response(@stream.stream_id, headers)
|
50
98
|
end
|
51
99
|
|
52
100
|
private
|
@@ -54,17 +102,18 @@ module GrpcKit
|
|
54
102
|
def read(last: false)
|
55
103
|
loop do
|
56
104
|
data = @stream.read_recv_data(last: last)
|
57
|
-
|
58
|
-
|
59
|
-
|
105
|
+
return data unless data.empty?
|
106
|
+
|
107
|
+
if @stream.close_remote?
|
108
|
+
# it do not receive data which we need, it may receive invalid grpc-status
|
109
|
+
unless @stream.end_read?
|
60
110
|
return nil
|
61
111
|
end
|
62
112
|
|
63
|
-
|
64
|
-
redo
|
113
|
+
return nil
|
65
114
|
end
|
66
115
|
|
67
|
-
|
116
|
+
@session.run_once
|
68
117
|
end
|
69
118
|
end
|
70
119
|
end
|
@@ -2,30 +2,34 @@
|
|
2
2
|
|
3
3
|
require 'grpc_kit/stream'
|
4
4
|
require 'grpc_kit/streams/send_buffer'
|
5
|
+
require 'grpc_kit/status_codes'
|
5
6
|
|
6
7
|
module GrpcKit
|
7
8
|
module Streams
|
8
9
|
class Client
|
9
|
-
def initialize(
|
10
|
-
@
|
10
|
+
def initialize(session:, config:, authority:)
|
11
|
+
@config = config
|
11
12
|
@session = session
|
12
|
-
@protobuf = protobuf
|
13
13
|
@stream = nil
|
14
14
|
@authority = authority
|
15
15
|
end
|
16
16
|
|
17
17
|
def send_msg(data, metadata: {}, timeout: nil, last: false)
|
18
18
|
if @stream
|
19
|
+
# unless metadata.empty?
|
20
|
+
# raise 'You can attach metadata at first send_msg' # XXX
|
21
|
+
# end
|
22
|
+
|
19
23
|
unless @stream.end_write?
|
20
24
|
@session.resume_data(@stream.stream_id)
|
21
25
|
end
|
22
26
|
else
|
23
27
|
headers = build_headers(metadata: metadata, timeout: timeout)
|
24
28
|
stream = @session.start_request(GrpcKit::Streams::SendBuffer.new, headers)
|
25
|
-
@stream = GrpcKit::Stream.new(protobuf: @protobuf, session: @session, stream: stream)
|
29
|
+
@stream = GrpcKit::Stream.new(protobuf: @config.protobuf, session: @session, stream: stream)
|
26
30
|
end
|
27
31
|
|
28
|
-
@stream.send(data, last: last)
|
32
|
+
@stream.send(data, last: last, limit_size: @config.max_send_message_size)
|
29
33
|
@session.run_once
|
30
34
|
end
|
31
35
|
|
@@ -42,7 +46,14 @@ module GrpcKit
|
|
42
46
|
raise 'You should call `send` method to send data'
|
43
47
|
end
|
44
48
|
|
45
|
-
@stream.recv(last: last)
|
49
|
+
data = @stream.recv(last: last, limit_size: @config.max_receive_message_size)
|
50
|
+
|
51
|
+
if data.nil?
|
52
|
+
check_status!
|
53
|
+
raise StopIteration
|
54
|
+
end
|
55
|
+
|
56
|
+
data
|
46
57
|
end
|
47
58
|
|
48
59
|
def close_and_recv
|
@@ -58,6 +69,8 @@ module GrpcKit
|
|
58
69
|
@session.start(@stream.stream_id)
|
59
70
|
@stream.end_read
|
60
71
|
|
72
|
+
check_status!
|
73
|
+
|
61
74
|
data = []
|
62
75
|
@stream.each { |d| data.push(d) }
|
63
76
|
data
|
@@ -65,11 +78,24 @@ module GrpcKit
|
|
65
78
|
|
66
79
|
private
|
67
80
|
|
81
|
+
def check_status!
|
82
|
+
# XXX: wait until half close (remote) to get grpc-status
|
83
|
+
until @stream.close_remote?
|
84
|
+
@session.run_once
|
85
|
+
end
|
86
|
+
|
87
|
+
if @stream.headers.grpc_status != GrpcKit::StatusCodes::OK
|
88
|
+
raise GrpcKit::Errors.from_status_code(@stream.headers.grpc_status, @stream.headers.status_message)
|
89
|
+
else
|
90
|
+
GrpcKit.logger.debug('request is success')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
68
94
|
def build_headers(metadata: {}, timeout: nil, **headers)
|
69
95
|
hdrs = metadata.merge(headers).merge(
|
70
96
|
':method' => 'POST',
|
71
97
|
':scheme' => 'http',
|
72
|
-
':path' => @path,
|
98
|
+
':path' => @config.path,
|
73
99
|
':authority' => @authority,
|
74
100
|
'te' => 'trailers',
|
75
101
|
'content-type' => 'application/grpc',
|
@@ -7,7 +7,7 @@ module GrpcKit
|
|
7
7
|
# @params compress [Boolean]
|
8
8
|
def pack(data, compress = false)
|
9
9
|
c = compress ? 1 : 0
|
10
|
-
[c, data.
|
10
|
+
[c, data.bytesize, data].pack('CNa*')
|
11
11
|
end
|
12
12
|
|
13
13
|
# @params data [String]
|
@@ -51,6 +51,7 @@ module GrpcKit
|
|
51
51
|
def read
|
52
52
|
metadata = @data.slice!(0, METADATA_SIZE)
|
53
53
|
c, size = metadata.unpack('CN')
|
54
|
+
# TODO: more efficient code
|
54
55
|
data = @data.slice!(0, size)
|
55
56
|
[c != 0, size, data]
|
56
57
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
|
5
5
|
require 'grpc_kit/stream'
|
6
|
+
require 'grpc_kit/status_codes'
|
6
7
|
|
7
8
|
module GrpcKit
|
8
9
|
module Streams
|
@@ -11,24 +12,41 @@ module GrpcKit
|
|
11
12
|
|
12
13
|
delegate %i[each recv] => :@stream
|
13
14
|
|
14
|
-
def initialize(
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@stream = GrpcKit::Stream.new(protobuf: @protobuf, session: @session, stream: stream)
|
15
|
+
def initialize(stream:, session:, config:)
|
16
|
+
@stream = GrpcKit::Stream.new(protobuf: config.protobuf, session: session, stream: stream)
|
17
|
+
@config = config
|
18
18
|
@sent_first_msg = false
|
19
19
|
end
|
20
20
|
|
21
21
|
def send_msg(data, last: false)
|
22
|
-
|
22
|
+
if last
|
23
|
+
@stream.send_trailer # TODO: pass trailer metadata
|
24
|
+
end
|
23
25
|
|
26
|
+
@stream.send(data, last: last, limit_size: @config.max_send_message_size)
|
24
27
|
return if @sent_first_msg
|
25
28
|
|
26
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
)
|
29
|
+
@stream.submit_response
|
30
|
+
@sent_first_msg = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def recv(last: false)
|
34
|
+
data = @stream.recv(last: last, limit_size: @config.max_receive_message_size)
|
35
|
+
raise StopIteration if data.nil?
|
36
|
+
|
37
|
+
data
|
38
|
+
end
|
39
|
+
|
40
|
+
def send_trailer
|
41
|
+
@stream.send_trailer # TODO: pass trailer metadata
|
42
|
+
@stream.end_write
|
43
|
+
end
|
44
|
+
|
45
|
+
def send_status(status: GrpcKit::StatusCodes::INTERNAL, msg: nil, metadata: {})
|
46
|
+
@stream.send_trailer(status: status, msg: msg, metadata: metadata)
|
47
|
+
return if @sent_first_msg
|
48
|
+
|
49
|
+
@stream.submit_response(piggyback_trailer: true)
|
32
50
|
@sent_first_msg = true
|
33
51
|
end
|
34
52
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ganmacs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ds9
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: grpc-tools
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.15.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.15.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: pry-byebug
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,7 +152,9 @@ files:
|
|
152
152
|
- LICENSE.txt
|
153
153
|
- README.md
|
154
154
|
- Rakefile
|
155
|
+
- TODO.md
|
155
156
|
- bin/console
|
157
|
+
- bin/nghttp2
|
156
158
|
- bin/setup
|
157
159
|
- examples/helloworld/helloworld.proto
|
158
160
|
- examples/helloworld/helloworld_pb.rb
|
@@ -190,6 +192,7 @@ files:
|
|
190
192
|
- lib/grpc_kit/rpcs/bidi_streamer.rb
|
191
193
|
- lib/grpc_kit/rpcs/call.rb
|
192
194
|
- lib/grpc_kit/rpcs/client_streamer.rb
|
195
|
+
- lib/grpc_kit/rpcs/error.rb
|
193
196
|
- lib/grpc_kit/rpcs/request_response.rb
|
194
197
|
- lib/grpc_kit/rpcs/server_streamer.rb
|
195
198
|
- lib/grpc_kit/server.rb
|
@@ -200,13 +203,13 @@ files:
|
|
200
203
|
- lib/grpc_kit/session/io.rb
|
201
204
|
- lib/grpc_kit/session/server.rb
|
202
205
|
- lib/grpc_kit/session/stream.rb
|
206
|
+
- lib/grpc_kit/session/stream_status.rb
|
203
207
|
- lib/grpc_kit/status_codes.rb
|
204
208
|
- lib/grpc_kit/stream.rb
|
205
209
|
- lib/grpc_kit/streams/client.rb
|
206
210
|
- lib/grpc_kit/streams/packable.rb
|
207
211
|
- lib/grpc_kit/streams/send_buffer.rb
|
208
212
|
- lib/grpc_kit/streams/server.rb
|
209
|
-
- lib/grpc_kit/streams/stream.rb
|
210
213
|
- lib/grpc_kit/version.rb
|
211
214
|
homepage: https://github.com/ganmacs/grpc_kit
|
212
215
|
licenses:
|