grpc_kit 0.1.8 → 0.1.9

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/examples/helloworld_client.rb +1 -1
  3. data/examples/routeguide_client.rb +33 -0
  4. data/examples/routeguide_server.rb +17 -0
  5. data/lib/grpc.rb +2 -1
  6. data/lib/grpc_kit.rb +4 -1
  7. data/lib/grpc_kit/calls.rb +17 -3
  8. data/lib/grpc_kit/calls/client_bidi_streamer.rb +63 -0
  9. data/lib/grpc_kit/calls/client_client_streamer.rb +8 -4
  10. data/lib/grpc_kit/calls/client_request_response.rb +7 -4
  11. data/lib/grpc_kit/calls/client_server_streamer.rb +7 -4
  12. data/lib/grpc_kit/calls/server_bidi_streamer.rb +43 -0
  13. data/lib/grpc_kit/calls/server_client_streamer.rb +5 -1
  14. data/lib/grpc_kit/calls/server_request_response.rb +5 -1
  15. data/lib/grpc_kit/calls/server_server_streamer.rb +5 -1
  16. data/lib/grpc_kit/client.rb +22 -4
  17. data/lib/grpc_kit/errors.rb +25 -11
  18. data/lib/grpc_kit/grpc/dsl.rb +17 -2
  19. data/lib/grpc_kit/grpc/generic_service.rb +0 -13
  20. data/lib/grpc_kit/grpc/interceptor.rb +27 -0
  21. data/lib/grpc_kit/grpc/logger.rb +4 -1
  22. data/lib/grpc_kit/grpc_time.rb +3 -1
  23. data/lib/grpc_kit/interceptors.rb +3 -0
  24. data/lib/grpc_kit/interceptors/client_bidi_streamer.rb +20 -0
  25. data/lib/grpc_kit/interceptors/client_client_streamer.rb +3 -0
  26. data/lib/grpc_kit/interceptors/client_request_response.rb +3 -0
  27. data/lib/grpc_kit/interceptors/client_server_streamer.rb +3 -0
  28. data/lib/grpc_kit/interceptors/server_bidi_streamer.rb +17 -0
  29. data/lib/grpc_kit/interceptors/server_client_streamer.rb +2 -0
  30. data/lib/grpc_kit/interceptors/server_request_response.rb +2 -0
  31. data/lib/grpc_kit/interceptors/server_server_streamer.rb +2 -0
  32. data/lib/grpc_kit/protobuffer.rb +8 -0
  33. data/lib/grpc_kit/rpc_desc.rb +21 -4
  34. data/lib/grpc_kit/rpcs.rb +4 -0
  35. data/lib/grpc_kit/rpcs/client_bidi_streamer.rb +20 -1
  36. data/lib/grpc_kit/rpcs/client_client_streamer.rb +5 -0
  37. data/lib/grpc_kit/rpcs/client_request_response.rb +11 -17
  38. data/lib/grpc_kit/rpcs/client_server_streamer.rb +5 -0
  39. data/lib/grpc_kit/rpcs/server_bidi_streamer.rb +17 -0
  40. data/lib/grpc_kit/rpcs/server_client_streamer.rb +3 -0
  41. data/lib/grpc_kit/rpcs/server_request_response.rb +3 -0
  42. data/lib/grpc_kit/rpcs/server_server_streamer.rb +3 -0
  43. data/lib/grpc_kit/server.rb +12 -4
  44. data/lib/grpc_kit/session/client_session.rb +7 -2
  45. data/lib/grpc_kit/session/drain_controller.rb +2 -0
  46. data/lib/grpc_kit/session/headers.rb +11 -0
  47. data/lib/grpc_kit/session/io.rb +9 -0
  48. data/lib/grpc_kit/session/recv_buffer.rb +7 -0
  49. data/lib/grpc_kit/session/send_buffer.rb +8 -0
  50. data/lib/grpc_kit/session/server_session.rb +8 -5
  51. data/lib/grpc_kit/session/stream.rb +17 -3
  52. data/lib/grpc_kit/session/stream_status.rb +7 -1
  53. data/lib/grpc_kit/stream/client_stream.rb +55 -9
  54. data/lib/grpc_kit/stream/server_stream.rb +19 -1
  55. data/lib/grpc_kit/transport/client_transport.rb +39 -3
  56. data/lib/grpc_kit/transport/packable.rb +9 -3
  57. data/lib/grpc_kit/transport/server_transport.rb +15 -2
  58. data/lib/grpc_kit/version.rb +1 -1
  59. metadata +6 -3
  60. data/TODO.md +0 -71
@@ -13,6 +13,8 @@ module GrpcKit
13
13
  @io.close
14
14
  end
15
15
 
16
+ # @param length [Integer]
17
+ # @return [DS9::ERR_WOULDBLOCK, DS9::ERR_EOF, String]
16
18
  def recv_event(length)
17
19
  data = @io.read_nonblock(length, nil, exception: false)
18
20
 
@@ -26,6 +28,8 @@ module GrpcKit
26
28
  end
27
29
  end
28
30
 
31
+ # @param data [String]
32
+ # @return [DS9::ERR_WOULDBLOCK, Integer]
29
33
  def send_event(data)
30
34
  return 0 if data.empty?
31
35
 
@@ -37,6 +41,8 @@ module GrpcKit
37
41
  end
38
42
  end
39
43
 
44
+ # Blocking until io object is readable
45
+ # @return [void]
40
46
  def wait_readable
41
47
  ::IO.select([@io], [], [])
42
48
  true
@@ -44,10 +50,13 @@ module GrpcKit
44
50
  false
45
51
  end
46
52
 
53
+ # Blocking until io object is readable or writable
54
+ # @return [void]
47
55
  def select(timeout = 1)
48
56
  ::IO.select([@io], [@io], [], timeout)
49
57
  end
50
58
 
59
+ # @return [void]
51
60
  def flush
52
61
  @io.flush
53
62
  end
@@ -8,10 +8,15 @@ module GrpcKit
8
8
  @end = false
9
9
  end
10
10
 
11
+ # @param data [String]
12
+ # @return [void]
11
13
  def write(data)
12
14
  @buffer << data
13
15
  end
14
16
 
17
+ # @param size [Integer,nil]
18
+ # @param last [Boolean]
19
+ # @return [String,nil]
15
20
  def read(size = nil, last: false)
16
21
  return nil if @buffer.empty?
17
22
 
@@ -29,10 +34,12 @@ module GrpcKit
29
34
  end
30
35
  end
31
36
 
37
+ # @return [Boolean]
32
38
  def end_read?
33
39
  @end
34
40
  end
35
41
 
42
+ # @return [void]
36
43
  def end_read
37
44
  @end = true
38
45
  end
@@ -9,23 +9,31 @@ module GrpcKit
9
9
  @deferred_read = false
10
10
  end
11
11
 
12
+ # @param data [String]
13
+ # @param last [Boolean]
14
+ # @return [void]
12
15
  def write(data, last: false)
13
16
  end_write if last
14
17
  @buffer << data
15
18
  end
16
19
 
20
+ # @return [Boolean]
17
21
  def need_resume?
18
22
  @deferred_read
19
23
  end
20
24
 
25
+ # @return [void]
21
26
  def end_write
22
27
  @end_write = true
23
28
  end
24
29
 
30
+ # @return [Boolean]
25
31
  def end_write?
26
32
  @end_write
27
33
  end
28
34
 
35
+ # @param size [Integer,nil]
36
+ # @return [nil,DS9::ERR_DEFERRED,String]
29
37
  def read(size = nil)
30
38
  if @buffer.empty?
31
39
  if end_write?
@@ -15,8 +15,8 @@ module GrpcKit
15
15
 
16
16
  delegate %i[send_event recv_event] => :@io
17
17
 
18
- # @params io [GrpcKit::Session::IO]
19
- # @params dispatcher [GrpcKit::Server]
18
+ # @param io [GrpcKit::Session::IO]
19
+ # @param dispatcher [GrpcKit::Server]
20
20
  def initialize(io, dispatcher)
21
21
  super() # initialize DS9::Session
22
22
 
@@ -29,6 +29,7 @@ module GrpcKit
29
29
  @drain = nil
30
30
  end
31
31
 
32
+ # @return [void]
32
33
  def start
33
34
  loop do
34
35
  invoke
@@ -81,10 +82,12 @@ module GrpcKit
81
82
  false
82
83
  end
83
84
 
85
+ # @return [void]
84
86
  def drain
85
87
  @drain ||= GrpcKit::Session::DrainController.new
86
88
  end
87
89
 
90
+ # @return [void]
88
91
  def shutdown
89
92
  stop
90
93
  @io.close
@@ -136,7 +139,7 @@ module GrpcKit
136
139
 
137
140
  # nghttp2_session_callbacks_set_on_frame_recv_callback
138
141
  def on_frame_recv(frame)
139
- # GrpcKit.logger.debug("on_frame_recv #{frame}") # Too many call
142
+ GrpcKit.logger.debug("on_frame_recv #{frame}") # Too many call
140
143
 
141
144
  case frame
142
145
  when DS9::Frames::Data
@@ -172,7 +175,7 @@ module GrpcKit
172
175
 
173
176
  # nghttp2_session_callbacks_set_on_frame_send_callback
174
177
  def on_frame_send(frame)
175
- # GrpcKit.logger.debug("on_frame_send #{frame}") # Too many call
178
+ GrpcKit.logger.debug("on_frame_send #{frame}") # Too many call
176
179
  case frame
177
180
  when DS9::Frames::Data, DS9::Frames::Headers
178
181
  if frame.end_stream?
@@ -204,7 +207,7 @@ module GrpcKit
204
207
 
205
208
  # nghttp2_session_callbacks_set_on_header_callback
206
209
  def on_header(name, value, frame, _flags)
207
- # GrpcKit.logger.debug("#{name} => #{value}") # Too many call
210
+ GrpcKit.logger.debug("#{name} => #{value}") # Too many call
208
211
  stream = @streams[frame.stream_id]
209
212
  stream.add_header(name, value)
210
213
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
4
  require 'grpc_kit/session/headers'
@@ -18,6 +18,9 @@ module GrpcKit
18
18
  attr_reader :headers, :pending_send_data, :pending_recv_data, :trailer_data, :status
19
19
  attr_accessor :inflight, :stream_id
20
20
 
21
+ # @param stream_id [Integer]
22
+ # @param send_data [GrpcKit::Session::SendBuffer]
23
+ # @param recv_data [GrpcKit::Session::RecvBuffer]
21
24
  def initialize(stream_id:, send_data: nil, recv_data: nil)
22
25
  @stream_id = stream_id
23
26
  @end_read_stream = false
@@ -31,22 +34,33 @@ module GrpcKit
31
34
  @draining = false
32
35
  end
33
36
 
37
+ # @return [void]
34
38
  def drain
35
39
  @draining = true
36
40
  end
37
41
 
38
- def write_trailers_data(tariler)
39
- @trailer_data = tariler
42
+ # @param tarilers [Hash<String,String>]
43
+ # @return [void]
44
+ def write_trailers_data(tarilers)
45
+ @trailer_data = tarilers
40
46
  end
41
47
 
48
+ # @param data [String]
49
+ # @param last [Boolean]
50
+ # @return [void]
42
51
  def write_send_data(data, last: false)
43
52
  @pending_send_data.write(data, last: last)
44
53
  end
45
54
 
55
+ # @param last [Boolean]
56
+ # @return [void]
46
57
  def read_recv_data(last: false)
47
58
  @pending_recv_data.read(last: last)
48
59
  end
49
60
 
61
+ # @param name [String]
62
+ # @param value [String]
63
+ # @return [void]
50
64
  def add_header(name, value)
51
65
  @headers.add(name, value)
52
66
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GrpcKit
4
4
  module Session
@@ -12,6 +12,7 @@ module GrpcKit
12
12
  @status = OPEN
13
13
  end
14
14
 
15
+ # @return [void]
15
16
  def close_local
16
17
  if @status == OPEN
17
18
  @status = HALF_CLOSE_LOCAL
@@ -24,6 +25,7 @@ module GrpcKit
24
25
  end
25
26
  end
26
27
 
28
+ # @return [void]
27
29
  def close_remote
28
30
  if @status == OPEN
29
31
  @status = HALF_CLOSE_REMOTE
@@ -36,18 +38,22 @@ module GrpcKit
36
38
  end
37
39
  end
38
40
 
41
+ # @return [void]
39
42
  def close
40
43
  @status = CLOSE
41
44
  end
42
45
 
46
+ # @return [Boolean]
43
47
  def close_local?
44
48
  (@status == HALF_CLOSE_LOCAL) || close?
45
49
  end
46
50
 
51
+ # @return [Boolean]
47
52
  def close_remote?
48
53
  (@status == HALF_CLOSE_REMOTE) || close?
49
54
  end
50
55
 
56
+ # @return [Boolean]
51
57
  def close?
52
58
  @status == CLOSE
53
59
  end
@@ -5,20 +5,25 @@ require 'grpc_kit/status_codes'
5
5
  module GrpcKit
6
6
  module Stream
7
7
  class ClientStream
8
- # @params transport [GrpcKit::Transport::ClientTransport]
9
- # @params config [GrpcKit::MethodConfig]
10
- # @params authority [String]
8
+ # @param transport [GrpcKit::Transport::ClientTransport]
9
+ # @param config [GrpcKit::MethodConfig]
10
+ # @param authority [String]
11
11
  def initialize(transport, config, authority:, timeout: nil)
12
12
  @transport = transport
13
13
  @config = config
14
14
 
15
15
  @authority = authority
16
16
  @timeout = timeout
17
+ @deadline = timeout&.to_absolute_time
17
18
 
18
19
  @started = false
19
20
  end
20
21
 
21
- def send_msg(data, metadata: {}, timeout: nil, last: false)
22
+ # @param data [Object]
23
+ # @param metadata [Hash<String,String>]
24
+ # @param last [Boolean]
25
+ # @return [void]
26
+ def send_msg(data, metadata: {}, last: false)
22
27
  buf =
23
28
  begin
24
29
  @config.protobuf.encode(data)
@@ -31,6 +36,10 @@ module GrpcKit
31
36
  raise GrpcKit::Errors::ResourceExhausted, "Sending message is too large: send=#{req.bytesize}, max=#{limit_size}"
32
37
  end
33
38
 
39
+ if @deadline && Time.now > @deadline
40
+ raise GrpcKit::Errors::DeadlineExceeded, @deadline
41
+ end
42
+
34
43
  if @started
35
44
  @transport.write_data(buf, last: last)
36
45
  else
@@ -44,12 +53,34 @@ module GrpcKit
44
53
  loop { yield(do_recv) }
45
54
  end
46
55
 
47
- def recv_msg(last: false)
56
+ # @raise [StopIteration] when recving message finished
57
+ # @param last [Boolean]
58
+ # @param blocking [Boolean]
59
+ # @return [Object]
60
+ def recv_msg(last: false, blocking: true)
61
+ validate_if_request_start!
62
+
63
+ ret = do_recv(last: last, blocking: blocking)
64
+
65
+ if @deadline && Time.now > @deadline
66
+ raise GrpcKit::Errors::DeadlineExceeded, @deadline
67
+ end
68
+
69
+ ret
70
+ end
71
+
72
+ def close_and_send
48
73
  validate_if_request_start!
49
74
 
50
- do_recv(last: last)
75
+ if @deadline && Time.now > @deadline
76
+ raise GrpcKit::Errors::DeadlineExceeded, @deadline
77
+ end
78
+
79
+ # send?
80
+ @transport.close_and_flush
51
81
  end
52
82
 
83
+ # @return [Array<Object>]
53
84
  def close_and_recv
54
85
  validate_if_request_start!
55
86
 
@@ -57,6 +88,11 @@ module GrpcKit
57
88
 
58
89
  data = []
59
90
  loop { data.push(do_recv) }
91
+
92
+ if @deadline && Time.now > @deadline
93
+ raise GrpcKit::Errors::DeadlineExceeded, @deadline
94
+ end
95
+
60
96
  data
61
97
  end
62
98
 
@@ -68,8 +104,18 @@ module GrpcKit
68
104
  end
69
105
  end
70
106
 
71
- def do_recv(last: false)
72
- data = @transport.read_data(last: last)
107
+ def do_recv(last: false, blocking: true)
108
+ data =
109
+ if blocking
110
+ @transport.read_data(last: last)
111
+ else
112
+ v = @transport.read_data_nonblock(last: last)
113
+ if v == :wait_readable
114
+ return v
115
+ end
116
+
117
+ v
118
+ end
73
119
 
74
120
  if data.nil?
75
121
  check_status!
@@ -126,7 +172,7 @@ module GrpcKit
126
172
  ':scheme' => 'http',
127
173
  ':path' => @config.path,
128
174
  ':authority' => authority,
129
- 'grpc-timeout' => timeout,
175
+ 'grpc-timeout' => timeout&.to_s,
130
176
  'te' => 'trailers',
131
177
  'content-type' => 'application/grpc',
132
178
  'user-agent' => "grpc-ruby/#{GrpcKit::VERSION} (grpc_kit)",
@@ -5,12 +5,13 @@ require 'grpc_kit/errors'
5
5
  module GrpcKit
6
6
  module Stream
7
7
  class ServerStream
8
- # @params transport [GrpcKit::transports::ServerTransport]
8
+ # @param transport [GrpcKit::transports::ServerTransport]
9
9
  def initialize(transport)
10
10
  @transport = transport
11
11
  @started = false
12
12
  end
13
13
 
14
+ # @return [void]
14
15
  def invoke(rpc)
15
16
  rpc.invoke(self, metadata: @transport.recv_headers.metadata)
16
17
  rescue GrpcKit::Errors::BadStatus => e
@@ -21,6 +22,13 @@ module GrpcKit
21
22
  send_status(status: GrpcKit::StatusCodes::UNKNOWN, msg: e.message, metadata: {})
22
23
  end
23
24
 
25
+ # @param data [Object]
26
+ # @param protobuf [GrpcKit::ProtoBuffer]
27
+ # @param last [Boolean]
28
+ # @param limit_size [Integer]
29
+ # @param initial_metadata [Hash<String,String>]
30
+ # @param trailing_metadata [Hash<String,String>]
31
+ # @return [void]
24
32
  def send_msg(data, protobuf, last: false, limit_size: nil, initial_metadata: {}, trailing_metadata: {})
25
33
  buf =
26
34
  begin
@@ -42,6 +50,11 @@ module GrpcKit
42
50
  end
43
51
  end
44
52
 
53
+ # @raise [StopIteration] when recving message finished
54
+ # @param protobuf [GrpcKit::ProtoBuffer]
55
+ # @param last [Boolean]
56
+ # @param limit_size [Integer]
57
+ # @return [Object]
45
58
  def recv_msg(protobuf, last: false, limit_size: nil)
46
59
  data = @transport.read_data(last: last)
47
60
 
@@ -68,10 +81,15 @@ module GrpcKit
68
81
  end
69
82
  end
70
83
 
84
+ # @param protobuf [GrpcKit::ProtoBuffer]
71
85
  def each(protobuf)
72
86
  loop { yield(recv_msg(protobuf)) }
73
87
  end
74
88
 
89
+ # @param status [GrpcKit::StatusCodes::BadStatus, GrpcKit::StatusCodes::OK]
90
+ # @param msg [String,nil]
91
+ # @param metadata [Hash<String,String>]
92
+ # @return [void]
75
93
  def send_status(data: nil, status: GrpcKit::StatusCodes::OK, msg: nil, metadata: {})
76
94
  t = build_trailers(status, msg, metadata)
77
95
  @transport.write_data(data, last: true) if data
@@ -7,17 +7,22 @@ module GrpcKit
7
7
  class ClientTransport
8
8
  include GrpcKit::Transport::Packable
9
9
 
10
- # @params session [GrpcKit::Session::ClientSession]
10
+ # @param session [GrpcKit::Session::ClientSession]
11
11
  def initialize(session)
12
12
  @session = session
13
13
  @stream = nil # set later
14
14
  end
15
15
 
16
- def start_request(data, header, last: false)
17
- @stream = @session.send_request(header)
16
+ # @param data [String]
17
+ # @param headers [Hash<String, String>]
18
+ # @param last [Boolean]
19
+ # @return [void]
20
+ def start_request(data, headers, last: false)
21
+ @stream = @session.send_request(headers)
18
22
  write_data(data, last: last)
19
23
  end
20
24
 
25
+ # @return [void]
21
26
  def close_and_flush
22
27
  @stream.end_write
23
28
  send_data
@@ -27,15 +32,33 @@ module GrpcKit
27
32
  @deferred = false
28
33
  end
29
34
 
35
+ # @param buf [String]
36
+ # @param last [Boolean]
37
+ # @return [void]
30
38
  def write_data(buf, last: false)
31
39
  write(@stream.pending_send_data, pack(buf), last: last)
32
40
  send_data
33
41
  end
34
42
 
43
+ # @param last [Boolean]
44
+ # @return [nil,String]
35
45
  def read_data(last: false)
36
46
  unpack(recv_data(last: last))
37
47
  end
38
48
 
49
+ # @param last [Boolean]
50
+ # @return [nil,String]
51
+ def read_data_nonblock(last: false)
52
+ data = nonblock_recv_data(last: last)
53
+ if data == :wait_readable
54
+ unpack(nil) # nil is needed read buffered data
55
+ :wait_readable
56
+ else
57
+ unpack(data)
58
+ end
59
+ end
60
+
61
+ # @return [Hash<String,String>]
39
62
  def recv_headers
40
63
  wait_close
41
64
  @stream.headers
@@ -54,6 +77,19 @@ module GrpcKit
54
77
  stream.write(buf, last: last)
55
78
  end
56
79
 
80
+ def nonblock_recv_data(last: false)
81
+ data = @stream.read_recv_data(last: last)
82
+ return data unless data.nil?
83
+
84
+ if @stream.close_remote?
85
+ return nil
86
+ end
87
+
88
+ @session.run_once
89
+
90
+ :wait_readable
91
+ end
92
+
57
93
  def recv_data(last: false)
58
94
  loop do
59
95
  data = @stream.read_recv_data(last: last)