grpc_kit 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +0 -3
- data/examples/interceptors/call_stream.rb +5 -0
- data/grpc_kit.gemspec +2 -2
- data/lib/grpc.rb +1 -1
- data/lib/grpc_kit/call.rb +1 -1
- data/lib/grpc_kit/calls/server_bidi_streamer.rb +2 -2
- data/lib/grpc_kit/calls/server_client_streamer.rb +2 -2
- data/lib/grpc_kit/calls/server_request_response.rb +2 -2
- data/lib/grpc_kit/calls/server_server_streamer.rb +2 -2
- data/lib/grpc_kit/client.rb +1 -1
- data/lib/grpc_kit/codec.rb +28 -0
- data/lib/grpc_kit/errors.rb +10 -9
- data/lib/grpc_kit/grpc/core.rb +1 -1
- data/lib/grpc_kit/grpc/dsl.rb +5 -5
- data/lib/grpc_kit/grpc/errors.rb +1 -1
- data/lib/grpc_kit/grpc/generic_service.rb +2 -2
- data/lib/grpc_kit/grpc/interceptor.rb +1 -1
- data/lib/grpc_kit/grpc/logger.rb +1 -1
- data/lib/grpc_kit/grpc/stream.rb +1 -1
- data/lib/grpc_kit/interceptor_registory.rb +2 -2
- data/lib/grpc_kit/interceptors/client_bidi_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors/client_client_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors/client_request_response.rb +1 -1
- data/lib/grpc_kit/interceptors/client_server_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors/server_bidi_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors/server_client_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors/server_request_response.rb +1 -1
- data/lib/grpc_kit/interceptors/server_server_streamer.rb +1 -1
- data/lib/grpc_kit/interceptors.rb +2 -2
- data/lib/grpc_kit/method_config.rb +5 -5
- data/lib/grpc_kit/rpc_desc.rb +24 -24
- data/lib/grpc_kit/rpcs.rb +1 -1
- data/lib/grpc_kit/server.rb +29 -24
- data/lib/grpc_kit/session/client_session.rb +17 -5
- data/lib/grpc_kit/session/drain_controller.rb +40 -16
- data/lib/grpc_kit/session/server_session.rb +15 -14
- data/lib/grpc_kit/stream/client_stream.rb +2 -2
- data/lib/grpc_kit/stream/server_stream.rb +6 -6
- data/lib/grpc_kit/version.rb +1 -1
- metadata +6 -6
- data/lib/grpc_kit/protobuffer.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 669ad89bc39849c66aeea640ba77ac6204e7cb1c2034a77b4bd4b698830c071a
|
4
|
+
data.tar.gz: fa4a14c0c2bf93837826b9477c126031849e95310f18f7633237d9a485688e56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c20fe45fbc01d727fdde2f70d1ebd53bcd2c89c03e9ef01e676a73344e7618aa7e32eaa07af71b10733cb79986fd1883647ba81a5e71b04779a8ded3c4bd8c4a
|
7
|
+
data.tar.gz: be9fb063cd523f9c6c2a47a58584a930f431378a050af865106126b1784ace126291d226c088884c7bd479423d86076439189856e7831341a1b22d7465443043
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -4,6 +4,7 @@ require 'grpc_kit'
|
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
class CallStream < GrpcKit::Call
|
7
|
+
include Enumerable
|
7
8
|
extend Forwardable
|
8
9
|
delegate %i[send_msg recv] => :@inner
|
9
10
|
|
@@ -12,6 +13,10 @@ class CallStream < GrpcKit::Call
|
|
12
13
|
@inner = inner
|
13
14
|
end
|
14
15
|
|
16
|
+
def each
|
17
|
+
loop { yield(recv) }
|
18
|
+
end
|
19
|
+
|
15
20
|
def method_missing(name, *args, &block)
|
16
21
|
@inner.public_send(name, *args, &block)
|
17
22
|
end
|
data/grpc_kit.gemspec
CHANGED
@@ -7,7 +7,7 @@ require 'grpc_kit/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'grpc_kit'
|
9
9
|
spec.version = GrpcKit::VERSION
|
10
|
-
spec.authors = ['
|
10
|
+
spec.authors = ['Yuta Iwama']
|
11
11
|
spec.email = ['ganmacs@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'A kit for creating gRPC server/client'
|
@@ -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.3.
|
25
|
+
spec.add_dependency 'ds9', '>= 1.3.3'
|
26
26
|
spec.add_dependency 'google-protobuf', '~> 3.6.1'
|
27
27
|
spec.add_dependency 'googleapis-common-protos-types', '~> 1.0.2'
|
28
28
|
|
data/lib/grpc.rb
CHANGED
data/lib/grpc_kit/call.rb
CHANGED
@@ -23,7 +23,7 @@ module GrpcKit
|
|
23
23
|
def send_msg(data)
|
24
24
|
@stream.send_msg(
|
25
25
|
data,
|
26
|
-
@
|
26
|
+
@codec,
|
27
27
|
initial_metadata: @outgoing_initial_metadata,
|
28
28
|
trailing_metadata: @outgoing_trailing_metadata,
|
29
29
|
limit_size: @config.max_send_message_size,
|
@@ -32,7 +32,7 @@ module GrpcKit
|
|
32
32
|
|
33
33
|
# @return [Object] response object
|
34
34
|
def recv
|
35
|
-
@stream.recv_msg(@
|
35
|
+
@stream.recv_msg(@codec, limit_size: @config.max_receive_message_size)
|
36
36
|
end
|
37
37
|
|
38
38
|
# @yieldparam response [Object] each response object of bidi streaming RPC
|
@@ -23,7 +23,7 @@ module GrpcKit
|
|
23
23
|
def send_msg(data)
|
24
24
|
@stream.send_msg(
|
25
25
|
data,
|
26
|
-
@
|
26
|
+
@codec,
|
27
27
|
last: true,
|
28
28
|
initial_metadata: @outgoing_initial_metadata,
|
29
29
|
trailing_metadata: @outgoing_trailing_metadata,
|
@@ -33,7 +33,7 @@ module GrpcKit
|
|
33
33
|
|
34
34
|
# @return [Object] response object
|
35
35
|
def recv
|
36
|
-
@stream.recv_msg(@
|
36
|
+
@stream.recv_msg(@codec, limit_size: @config.max_receive_message_size)
|
37
37
|
end
|
38
38
|
|
39
39
|
# @yieldparam response [Object] each response object of client streaming RPC
|
@@ -22,7 +22,7 @@ module GrpcKit
|
|
22
22
|
def send_msg(data)
|
23
23
|
@stream.send_msg(
|
24
24
|
data,
|
25
|
-
@
|
25
|
+
@codec,
|
26
26
|
last: true,
|
27
27
|
initial_metadata: @outgoing_initial_metadata,
|
28
28
|
trailing_metadata: @outgoing_trailing_metadata,
|
@@ -32,7 +32,7 @@ module GrpcKit
|
|
32
32
|
|
33
33
|
# @return [Object] response object
|
34
34
|
def recv
|
35
|
-
@stream.recv_msg(@
|
35
|
+
@stream.recv_msg(@codec, last: true, limit_size: @config.max_receive_message_size)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -21,7 +21,7 @@ module GrpcKit
|
|
21
21
|
def send_msg(data)
|
22
22
|
@stream.send_msg(
|
23
23
|
data,
|
24
|
-
@
|
24
|
+
@codec,
|
25
25
|
initial_metadata: @outgoing_initial_metadata,
|
26
26
|
trailing_metadata: @outgoing_trailing_metadata,
|
27
27
|
limit_size: @config.max_send_message_size,
|
@@ -30,7 +30,7 @@ module GrpcKit
|
|
30
30
|
|
31
31
|
# @return [Object] response object
|
32
32
|
def recv
|
33
|
-
@stream.recv_msg(@
|
33
|
+
@stream.recv_msg(@codec, last: true, limit_size: @config.max_receive_message_size)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
data/lib/grpc_kit/client.rb
CHANGED
@@ -10,7 +10,7 @@ module GrpcKit
|
|
10
10
|
class Client
|
11
11
|
# @param sock [TCPSocket]
|
12
12
|
# @param authority [nil, String]
|
13
|
-
# @param interceptors [Array<GrpcKit::
|
13
|
+
# @param interceptors [Array<GrpcKit::Grpc::ClientInterceptor>] list of interceptors
|
14
14
|
# @param timeout [nil, Integer, String]
|
15
15
|
def initialize(sock, authority: nil, interceptors: [], timeout: nil)
|
16
16
|
@sock = sock
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
class Codec
|
5
|
+
# @param marshal [Class, GrpcKit::Grpc::Stream]
|
6
|
+
# @param unmarshal [Class, GrpcKit::Grpc::Stream]
|
7
|
+
# @param marshal_method [Symbol]
|
8
|
+
# @param unmarshal_method [Symbol]
|
9
|
+
def initialize(marshal:, unmarshal:, marshal_method:, unmarshal_method:)
|
10
|
+
@marshal = marshal
|
11
|
+
@unmarshal = unmarshal
|
12
|
+
@marshal_method = marshal_method
|
13
|
+
@unmarshal_method = unmarshal_method
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param data [String]
|
17
|
+
# @return [String]
|
18
|
+
def encode(data)
|
19
|
+
@marshal.send(@marshal_method, data)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param data [String]
|
23
|
+
# @return [String]
|
24
|
+
def decode(data)
|
25
|
+
@unmarshal.send(@unmarshal_method, data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/grpc_kit/errors.rb
CHANGED
@@ -10,7 +10,16 @@ module GrpcKit
|
|
10
10
|
# @param message [String]
|
11
11
|
# @return [GrpcKit::Errors::BadStatus]
|
12
12
|
def self.from_status_code(code, message)
|
13
|
-
|
13
|
+
if code == GrpcKit::StatusCodes::OK
|
14
|
+
raise ArgumentError, 'Status OK is not an error'
|
15
|
+
end
|
16
|
+
|
17
|
+
error_class = CODES[code]
|
18
|
+
if error_class
|
19
|
+
error_class.new(message)
|
20
|
+
else
|
21
|
+
GrpcKit::Errors::Unknown.new("Received unknown code: code=#{code}\n #{message}")
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
25
|
class BadStatus < StandardError
|
@@ -29,13 +38,6 @@ module GrpcKit
|
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
32
|
-
class Ok < BadStatus
|
33
|
-
# @param message [String]
|
34
|
-
def initialize(message)
|
35
|
-
super(GrpcKit::StatusCodes::OK, message)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
41
|
class Cancelled < BadStatus
|
40
42
|
# @param message [String]
|
41
43
|
def initialize(message)
|
@@ -156,7 +158,6 @@ module GrpcKit
|
|
156
158
|
end
|
157
159
|
|
158
160
|
CODES = {
|
159
|
-
GrpcKit::StatusCodes::OK => Ok,
|
160
161
|
GrpcKit::StatusCodes::CANCELLED => Cancelled,
|
161
162
|
GrpcKit::StatusCodes::UNKNOWN => Unknown,
|
162
163
|
GrpcKit::StatusCodes::INVALID_ARGUMENT => InvalidArgument,
|
data/lib/grpc_kit/grpc/core.rb
CHANGED
data/lib/grpc_kit/grpc/dsl.rb
CHANGED
@@ -6,7 +6,7 @@ require 'grpc_kit/client'
|
|
6
6
|
require 'grpc_kit/grpc/stream'
|
7
7
|
|
8
8
|
module GrpcKit
|
9
|
-
module
|
9
|
+
module Grpc
|
10
10
|
module Dsl
|
11
11
|
# @param value [String]
|
12
12
|
attr_accessor :service_name
|
@@ -23,8 +23,8 @@ module GrpcKit
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# @param name [Symbol] gRPC method name
|
26
|
-
# @param marshal [Class, GrpcKit::
|
27
|
-
# @param unmarshal [Class, GrpcKit::
|
26
|
+
# @param marshal [Class, GrpcKit::Grpc::Stream] marshaling object
|
27
|
+
# @param unmarshal [Class, GrpcKit::Grpc::Stream] unmarshaling object
|
28
28
|
# @return [void]
|
29
29
|
def rpc(name, marshal, unmarshal)
|
30
30
|
if rpc_descs.key?(name)
|
@@ -55,9 +55,9 @@ module GrpcKit
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
# @return [GrpcKit::
|
58
|
+
# @return [GrpcKit::Grpc::Stream]
|
59
59
|
def stream(cls)
|
60
|
-
GrpcKit::
|
60
|
+
GrpcKit::Grpc::Stream.new(cls)
|
61
61
|
end
|
62
62
|
|
63
63
|
# @return [GrpcKit::Client]
|
data/lib/grpc_kit/grpc/errors.rb
CHANGED
data/lib/grpc_kit/grpc/logger.rb
CHANGED
data/lib/grpc_kit/grpc/stream.rb
CHANGED
@@ -24,11 +24,11 @@ module GrpcKit
|
|
24
24
|
end
|
25
25
|
|
26
26
|
invalid_interceptors = @interceptors.reject do |interceptor|
|
27
|
-
interceptor.class.ancestors.include?(GrpcKit::
|
27
|
+
interceptor.class.ancestors.include?(GrpcKit::Grpc::Interceptor)
|
28
28
|
end
|
29
29
|
|
30
30
|
unless invalid_interceptors.empty?
|
31
|
-
raise ArgumentError, "interceptor #{invalid_interceptors} must descend from #{GrpcKit::
|
31
|
+
raise ArgumentError, "interceptor #{invalid_interceptors.join(', ')} must descend from #{GrpcKit::Grpc::Interceptor}"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -7,7 +7,7 @@ module GrpcKit
|
|
7
7
|
class BidiStreamer < Streaming
|
8
8
|
private
|
9
9
|
|
10
|
-
# @param interceptor [GrpcKit::
|
10
|
+
# @param interceptor [GrpcKit::Grpc::ClientInterceptor]
|
11
11
|
# @param call [GrpcKit::Calls::Client::BidiStreamer]
|
12
12
|
# @param metadata [Hash<String,String>]
|
13
13
|
def invoke(interceptor, call, metadata)
|
@@ -7,7 +7,7 @@ module GrpcKit
|
|
7
7
|
class ClientStreamer < Streaming
|
8
8
|
private
|
9
9
|
|
10
|
-
# @param interceptor [GrpcKit::
|
10
|
+
# @param interceptor [GrpcKit::Grpc::ClientInterceptor]
|
11
11
|
# @param call [GrpcKit::Calls::Client::ClientStreamer]
|
12
12
|
# @param metadata [Hash<String,String>]
|
13
13
|
def invoke(interceptor, call, metadata)
|
@@ -5,7 +5,7 @@ require 'grpc_kit/interceptors'
|
|
5
5
|
module GrpcKit
|
6
6
|
module Interceptors::Client
|
7
7
|
class RequestResponse
|
8
|
-
# @param interceptors [Array<GrpcKit::
|
8
|
+
# @param interceptors [Array<GrpcKit::Grpc::ClientInterceptor>]
|
9
9
|
def initialize(interceptors)
|
10
10
|
@registry = GrpcKit::InterceptorRegistry.new(interceptors)
|
11
11
|
end
|
@@ -7,7 +7,7 @@ module GrpcKit
|
|
7
7
|
class ServerStreamer < Streaming
|
8
8
|
private
|
9
9
|
|
10
|
-
# @param interceptor [GrpcKit::
|
10
|
+
# @param interceptor [GrpcKit::Grpc::ClientInterceptor]
|
11
11
|
# @param call [GrpcKit::Calls::Client::ServerStreamer]
|
12
12
|
# @param metadata [Hash<String,String>]
|
13
13
|
def invoke(interceptor, call, metadata)
|
@@ -5,7 +5,7 @@ require 'grpc_kit/interceptors'
|
|
5
5
|
module GrpcKit
|
6
6
|
module Interceptors::Server
|
7
7
|
class BidiStreamer < Streaming
|
8
|
-
# @param interceptor [GrpcKit::
|
8
|
+
# @param interceptor [GrpcKit::Grpc::ServerInterceptor]
|
9
9
|
# @param call [GrpcKit::Calls::Client::BidiStreamer]
|
10
10
|
def invoke(interceptor, call)
|
11
11
|
interceptor.bidi_streamer(call: call, method: call.method) do |new_call = nil|
|
@@ -5,7 +5,7 @@ require 'grpc_kit/interceptors'
|
|
5
5
|
module GrpcKit
|
6
6
|
module Interceptors::Server
|
7
7
|
class ClientStreamer < Streaming
|
8
|
-
# @param interceptor [GrpcKit::
|
8
|
+
# @param interceptor [GrpcKit::Grpc::ServerInterceptor]
|
9
9
|
# @param call [GrpcKit::Calls::Client::ClientStreamer]
|
10
10
|
def invoke(interceptor, call)
|
11
11
|
interceptor.client_streamer(call: call, method: call.method) do |new_call = nil|
|
@@ -6,7 +6,7 @@ require 'grpc_kit/interceptor_registory'
|
|
6
6
|
module GrpcKit
|
7
7
|
module Interceptors::Server
|
8
8
|
class RequestResponse
|
9
|
-
# @param interceptors [Array<GrpcKit::
|
9
|
+
# @param interceptors [Array<GrpcKit::Grpc::ServerInterceptor>]
|
10
10
|
def initialize(interceptors)
|
11
11
|
@registry = GrpcKit::InterceptorRegistry.new(interceptors)
|
12
12
|
end
|
@@ -5,7 +5,7 @@ require 'grpc_kit/interceptors'
|
|
5
5
|
module GrpcKit
|
6
6
|
module Interceptors::Server
|
7
7
|
class ServerStreamer < Streaming
|
8
|
-
# @param interceptor [GrpcKit::
|
8
|
+
# @param interceptor [GrpcKit::Grpc::ServerInterceptor]
|
9
9
|
# @param call [GrpcKit::Calls::Client::ServerStreamer]
|
10
10
|
def invoke(interceptor, call)
|
11
11
|
# We don't need a `:request` parameter but,
|
@@ -6,7 +6,7 @@ module GrpcKit
|
|
6
6
|
module Interceptors
|
7
7
|
module Client
|
8
8
|
class Streaming
|
9
|
-
# @param interceptors [Array<GrpcKit::
|
9
|
+
# @param interceptors [Array<GrpcKit::Grpc::ClientInterceptor>]
|
10
10
|
def initialize(interceptors)
|
11
11
|
@registry = GrpcKit::InterceptorRegistry.new(interceptors)
|
12
12
|
end
|
@@ -35,7 +35,7 @@ module GrpcKit
|
|
35
35
|
|
36
36
|
module Server
|
37
37
|
class Streaming
|
38
|
-
# @param interceptors [Array<GrpcKit::
|
38
|
+
# @param interceptors [Array<GrpcKit::Grpc::ServerInterceptor>]
|
39
39
|
def initialize(interceptors)
|
40
40
|
@registry = GrpcKit::InterceptorRegistry.new(interceptors)
|
41
41
|
end
|
@@ -4,7 +4,7 @@ module GrpcKit
|
|
4
4
|
MethodConfig = Struct.new(
|
5
5
|
:path,
|
6
6
|
:ruby_style_method_name,
|
7
|
-
:
|
7
|
+
:codec,
|
8
8
|
:interceptor,
|
9
9
|
:service_name,
|
10
10
|
:method_name,
|
@@ -18,17 +18,17 @@ module GrpcKit
|
|
18
18
|
MAX_CLIENT_SEND_MESSAGE_SIZE = 1024 * 1024 * 4
|
19
19
|
|
20
20
|
def self.build_for_server(
|
21
|
-
path:, ruby_style_method_name:,
|
21
|
+
path:, ruby_style_method_name:, codec:, service_name:, method_name:, interceptor:,
|
22
22
|
max_receive_message_size: MAX_SERVER_RECEIVE_MESSAGE_SIZE, max_send_message_size: MAX_SERVER_SEND_MESSAGE_SIZE, compressor_type: ''
|
23
23
|
)
|
24
|
-
new(path, ruby_style_method_name,
|
24
|
+
new(path, ruby_style_method_name, codec, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
|
25
25
|
end
|
26
26
|
|
27
27
|
def self.build_for_client(
|
28
|
-
path:, ruby_style_method_name:,
|
28
|
+
path:, ruby_style_method_name:, codec:, service_name:, method_name:, interceptor:,
|
29
29
|
max_receive_message_size: MAX_CLIENT_RECEIVE_MESSAGE_SIZE, max_send_message_size: MAX_CLIENT_SEND_MESSAGE_SIZE, compressor_type: ''
|
30
30
|
)
|
31
|
-
new(path, ruby_style_method_name,
|
31
|
+
new(path, ruby_style_method_name, codec, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/grpc_kit/rpc_desc.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'grpc_kit/method_config'
|
4
|
-
require 'grpc_kit/
|
4
|
+
require 'grpc_kit/codec'
|
5
5
|
|
6
6
|
require 'grpc_kit/interceptors/client_request_response'
|
7
7
|
require 'grpc_kit/interceptors/client_client_streamer'
|
@@ -24,8 +24,8 @@ require 'grpc_kit/rpcs/server_bidi_streamer'
|
|
24
24
|
module GrpcKit
|
25
25
|
class RpcDesc
|
26
26
|
# @param name [Symbol] path name
|
27
|
-
# @param marshal [Class, GrpcKit::
|
28
|
-
# @param unmarshal [Class, GrpcKit::
|
27
|
+
# @param marshal [Class, GrpcKit::Grpc::Stream] marshaling object
|
28
|
+
# @param unmarshal [Class, GrpcKit::Grpc::Stream] unmarshaling object
|
29
29
|
# @param marshal_method [Symbol] method name of marshaling which marshal is called this method
|
30
30
|
# @param unmarshal_method [Symbol] method name of unmarshaling which unmarshal is called this method
|
31
31
|
# @param service_name [String]
|
@@ -38,8 +38,8 @@ module GrpcKit
|
|
38
38
|
@service_name = service_name
|
39
39
|
end
|
40
40
|
|
41
|
-
# @param handler [GrpcKit::
|
42
|
-
# @param interceptors [Array<GrpcKit::
|
41
|
+
# @param handler [GrpcKit::Grpc::GenericService]
|
42
|
+
# @param interceptors [Array<GrpcKit::Grpc::ServerInterceptor>]
|
43
43
|
# @return [#invoke] Server version of rpc class
|
44
44
|
def build_server(handler, interceptors: [])
|
45
45
|
inter = interceptors.empty? ? nil : server_interceptor.new(interceptors)
|
@@ -47,7 +47,7 @@ module GrpcKit
|
|
47
47
|
config = GrpcKit::MethodConfig.build_for_server(
|
48
48
|
path: path,
|
49
49
|
ruby_style_method_name: ruby_style_name,
|
50
|
-
|
50
|
+
codec: server_codec,
|
51
51
|
service_name: @service_name,
|
52
52
|
method_name: @name,
|
53
53
|
interceptor: inter,
|
@@ -55,7 +55,7 @@ module GrpcKit
|
|
55
55
|
server.new(handler, config)
|
56
56
|
end
|
57
57
|
|
58
|
-
# @param interceptors [Array<GrpcKit::
|
58
|
+
# @param interceptors [Array<GrpcKit::Grpc::ClientInterceptor>]
|
59
59
|
# @return [#invoke] Client version of rpc class
|
60
60
|
def build_client(interceptors: [])
|
61
61
|
inter = interceptors.empty? ? nil : client_interceptor.new(interceptors)
|
@@ -63,7 +63,7 @@ module GrpcKit
|
|
63
63
|
config = GrpcKit::MethodConfig.build_for_client(
|
64
64
|
path: path,
|
65
65
|
ruby_style_method_name: ruby_style_name,
|
66
|
-
|
66
|
+
codec: client_codec,
|
67
67
|
service_name: @service_name,
|
68
68
|
method_name: @name,
|
69
69
|
interceptor: inter,
|
@@ -83,22 +83,22 @@ module GrpcKit
|
|
83
83
|
|
84
84
|
# @return [Boolean]
|
85
85
|
def request_response?
|
86
|
-
!@marshal.is_a?(GrpcKit::
|
86
|
+
!@marshal.is_a?(GrpcKit::Grpc::Stream) && !@unmarshal.is_a?(GrpcKit::Grpc::Stream)
|
87
87
|
end
|
88
88
|
|
89
89
|
# @return [Boolean]
|
90
90
|
def client_streamer?
|
91
|
-
@marshal.is_a?(GrpcKit::
|
91
|
+
@marshal.is_a?(GrpcKit::Grpc::Stream) && !@unmarshal.is_a?(GrpcKit::Grpc::Stream)
|
92
92
|
end
|
93
93
|
|
94
94
|
# @return [Boolean]
|
95
95
|
def server_streamer?
|
96
|
-
!@marshal.is_a?(GrpcKit::
|
96
|
+
!@marshal.is_a?(GrpcKit::Grpc::Stream) && @unmarshal.is_a?(GrpcKit::Grpc::Stream)
|
97
97
|
end
|
98
98
|
|
99
99
|
# @return [Boolean]
|
100
100
|
def bidi_streamer?
|
101
|
-
@marshal.is_a?(GrpcKit::
|
101
|
+
@marshal.is_a?(GrpcKit::Grpc::Stream) && @unmarshal.is_a?(GrpcKit::Grpc::Stream)
|
102
102
|
end
|
103
103
|
|
104
104
|
private
|
@@ -129,21 +129,21 @@ module GrpcKit
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
def
|
133
|
-
@
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
def server_codec
|
133
|
+
@server_codec ||= Codec.new(
|
134
|
+
marshal: @unmarshal,
|
135
|
+
unmarshal: @marshal,
|
136
|
+
marshal_method: @marshal_method,
|
137
|
+
unmarshal_method: @unmarshal_method,
|
138
138
|
)
|
139
139
|
end
|
140
140
|
|
141
|
-
def
|
142
|
-
@
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
141
|
+
def client_codec
|
142
|
+
@client_codec ||= Codec.new(
|
143
|
+
marshal: @marshal,
|
144
|
+
unmarshal: @unmarshal,
|
145
|
+
marshal_method: @marshal_method,
|
146
|
+
unmarshal_method: @unmarshal_method,
|
147
147
|
)
|
148
148
|
end
|
149
149
|
|
data/lib/grpc_kit/rpcs.rb
CHANGED
data/lib/grpc_kit/server.rb
CHANGED
@@ -5,24 +5,25 @@ require 'grpc_kit/session/server_session'
|
|
5
5
|
|
6
6
|
module GrpcKit
|
7
7
|
class Server
|
8
|
-
# @param interceptors [Array<GrpcKit::
|
9
|
-
|
8
|
+
# @param interceptors [Array<GrpcKit::Grpc::ServerInterceptor>] list of interceptors
|
9
|
+
# @param shutdown_timeout [Integer] Number of seconds to wait for the server shutdown
|
10
|
+
def initialize(interceptors: [], shutdown_timeout: 30)
|
11
|
+
@interceptors = interceptors
|
12
|
+
@shutdown_timeout = shutdown_timeout
|
10
13
|
@sessions = []
|
11
14
|
@rpc_descs = {}
|
12
|
-
@interceptors = interceptors
|
13
15
|
@mutex = Mutex.new
|
14
16
|
@stopping = false
|
15
|
-
@max_graceful_wait = 60
|
16
17
|
|
17
18
|
GrpcKit.logger.debug("Launched grpc_kit(v#{GrpcKit::VERSION})")
|
18
19
|
end
|
19
20
|
|
20
|
-
# @param handler [GrpcKit::
|
21
|
+
# @param handler [GrpcKit::Grpc::GenericService] gRPC handler object or class
|
21
22
|
# @return [void]
|
22
23
|
def handle(handler)
|
23
24
|
klass = handler.is_a?(Class) ? handler : handler.class
|
24
|
-
unless klass.include?(GrpcKit::
|
25
|
-
raise "#{klass} must include
|
25
|
+
unless klass.include?(GrpcKit::Grpc::GenericService)
|
26
|
+
raise "#{klass} must include Grpc::GenericService"
|
26
27
|
end
|
27
28
|
|
28
29
|
klass.rpc_descs.each do |path, rpc_desc|
|
@@ -49,34 +50,34 @@ module GrpcKit
|
|
49
50
|
# This method is expected to be called in trap context
|
50
51
|
# @return [void]
|
51
52
|
def force_shutdown
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
53
|
+
@stopping = true
|
54
|
+
|
55
|
+
Thread.new {
|
56
|
+
GrpcKit.logger.debug('force shutdown')
|
57
|
+
shutdown_sessions
|
58
|
+
}
|
59
59
|
end
|
60
60
|
|
61
61
|
# This method is expected to be called in trap context
|
62
62
|
# @return [void]
|
63
63
|
def graceful_shutdown
|
64
|
+
@stopping = true
|
65
|
+
|
64
66
|
Thread.new do
|
65
67
|
GrpcKit.logger.debug('graceful shutdown')
|
66
68
|
@mutex.synchronize { @sessions.each(&:drain) }
|
67
|
-
@stopping = true
|
68
|
-
|
69
|
-
begin
|
70
|
-
Timeout.timeout(@max_graceful_wait) do
|
71
|
-
loop do
|
72
|
-
break if @sessions.empty?
|
73
69
|
|
74
|
-
|
75
|
-
|
70
|
+
end_time = Time.now + @shutdown_timeout
|
71
|
+
until end_time < Time.now
|
72
|
+
if @sessions.empty?
|
73
|
+
return
|
76
74
|
end
|
77
|
-
|
78
|
-
|
75
|
+
|
76
|
+
sleep 1
|
79
77
|
end
|
78
|
+
|
79
|
+
GrpcKit.logger.error('Timeout graceful shutdown. perform force shutdown')
|
80
|
+
shutdown_sessions
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
@@ -100,6 +101,10 @@ module GrpcKit
|
|
100
101
|
|
101
102
|
private
|
102
103
|
|
104
|
+
def shutdown_sessions
|
105
|
+
@mutex.synchronize { @sessions.each(&:shutdown) }
|
106
|
+
end
|
107
|
+
|
103
108
|
def establish_session(conn)
|
104
109
|
session = GrpcKit::Session::ServerSession.new(GrpcKit::Session::IO.new(conn), self)
|
105
110
|
begin
|
@@ -26,6 +26,7 @@ module GrpcKit
|
|
26
26
|
@opts = opts
|
27
27
|
@draining = false
|
28
28
|
@stop = false
|
29
|
+
@no_write_data = false
|
29
30
|
end
|
30
31
|
|
31
32
|
# @param headers [Hash<String,String>]
|
@@ -39,6 +40,7 @@ module GrpcKit
|
|
39
40
|
stream_id = submit_request(headers, stream.pending_send_data).to_i
|
40
41
|
stream.stream_id = stream_id
|
41
42
|
@streams[stream_id] = stream
|
43
|
+
@no_write_data = false
|
42
44
|
stream
|
43
45
|
end
|
44
46
|
|
@@ -67,12 +69,21 @@ module GrpcKit
|
|
67
69
|
raise 'trasport is closing'
|
68
70
|
end
|
69
71
|
|
70
|
-
if
|
71
|
-
|
72
|
-
end
|
72
|
+
if @no_write_data
|
73
|
+
@io.wait_readable
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
if want_read?
|
76
|
+
do_read
|
77
|
+
end
|
78
|
+
else
|
79
|
+
rs, ws = @io.select
|
80
|
+
if !rs.empty? && want_read?
|
81
|
+
do_read
|
82
|
+
end
|
83
|
+
|
84
|
+
if !ws.empty? && want_write?
|
85
|
+
send
|
86
|
+
end
|
76
87
|
end
|
77
88
|
end
|
78
89
|
|
@@ -133,6 +144,7 @@ module GrpcKit
|
|
133
144
|
stream = @streams[frame.stream_id]
|
134
145
|
if frame.end_stream?
|
135
146
|
stream.close_local
|
147
|
+
@no_write_data = @streams.all? { |_, v| v.close_local? }
|
136
148
|
end
|
137
149
|
end
|
138
150
|
|
@@ -5,33 +5,57 @@ require 'ds9'
|
|
5
5
|
module GrpcKit
|
6
6
|
module Session
|
7
7
|
class DrainController
|
8
|
+
module Status
|
9
|
+
NOT_START = 0
|
10
|
+
STARTED = 1
|
11
|
+
SENT_PING = 2
|
12
|
+
RECV_PING_ACK = 3
|
13
|
+
SENT_GOAWAY = 4
|
14
|
+
end
|
15
|
+
|
8
16
|
def initialize
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
@status = Status::NOT_START
|
18
|
+
end
|
19
|
+
|
20
|
+
def start_draining?
|
21
|
+
@status > Status::NOT_START
|
22
|
+
end
|
23
|
+
|
24
|
+
def start_draining
|
25
|
+
@status = Status::STARTED
|
13
26
|
end
|
14
27
|
|
15
28
|
# @return [void]
|
16
29
|
def recv_ping_ack
|
17
|
-
@
|
30
|
+
if @status == Status::SENT_PING
|
31
|
+
next_step
|
32
|
+
end
|
18
33
|
end
|
19
34
|
|
20
35
|
# @return [void]
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
@goaway_sent = true
|
27
|
-
# elsif @sent_shutdown_notice && !@after_one_rtt && !@sent_ping
|
28
|
-
# @sent_ping = true
|
29
|
-
elsif !@sent_shutdown_notice
|
36
|
+
def next(session)
|
37
|
+
case @status
|
38
|
+
when Status::NOT_START
|
39
|
+
# next_step
|
40
|
+
when Status::STARTED
|
30
41
|
session.submit_shutdown
|
31
|
-
|
32
|
-
|
42
|
+
session.submit_ping
|
43
|
+
next_step
|
44
|
+
when Status::SENT_PING
|
45
|
+
# skip until #recv_ping_ack is called (1RTT)
|
46
|
+
when Status::RECV_PING_ACK
|
47
|
+
session.submit_goaway(DS9::NO_ERROR, session.last_proc_stream_id)
|
48
|
+
next_step
|
49
|
+
when Status::SENT_GOAWAY
|
50
|
+
session.shutdown
|
33
51
|
end
|
34
52
|
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def next_step
|
57
|
+
@status += 1
|
58
|
+
end
|
35
59
|
end
|
36
60
|
end
|
37
61
|
end
|
@@ -24,9 +24,8 @@ module GrpcKit
|
|
24
24
|
@streams = {}
|
25
25
|
@stop = false
|
26
26
|
@dispatcher = dispatcher
|
27
|
-
@peer_shutdowned = false
|
28
27
|
@inflights = []
|
29
|
-
@
|
28
|
+
@drain_controller = GrpcKit::Session::DrainController.new
|
30
29
|
end
|
31
30
|
|
32
31
|
# @return [void]
|
@@ -50,19 +49,19 @@ module GrpcKit
|
|
50
49
|
|
51
50
|
# @return [bool] return session can continue
|
52
51
|
def run_once
|
53
|
-
if @
|
52
|
+
if @stop || !(want_read? || want_write?)
|
54
53
|
# it could be called twice
|
55
54
|
@streams.each_value(&:close)
|
56
55
|
return false
|
57
56
|
end
|
58
57
|
|
59
|
-
if @
|
58
|
+
if @drain_controller.start_draining?
|
60
59
|
if @streams.empty?
|
61
60
|
shutdown
|
62
|
-
return
|
61
|
+
return false
|
63
62
|
end
|
64
63
|
|
65
|
-
@
|
64
|
+
@drain_controller.next(self)
|
66
65
|
end
|
67
66
|
|
68
67
|
rs, ws = @io.select
|
@@ -84,7 +83,7 @@ module GrpcKit
|
|
84
83
|
|
85
84
|
# @return [void]
|
86
85
|
def drain
|
87
|
-
@
|
86
|
+
@drain_controller.start_draining
|
88
87
|
end
|
89
88
|
|
90
89
|
# @return [void]
|
@@ -113,13 +112,15 @@ module GrpcKit
|
|
113
112
|
receive
|
114
113
|
rescue DS9::Exception => e
|
115
114
|
shutdown
|
116
|
-
if DS9::ERR_EOF == e.code
|
117
|
-
@peer_shutdowned = true
|
118
|
-
return
|
119
|
-
# raise EOFError
|
120
|
-
end
|
121
115
|
|
122
|
-
|
116
|
+
case e.code
|
117
|
+
when DS9::ERR_EOF
|
118
|
+
GrpcKit.logger.debug('The peer performed a shutdown on the connection')
|
119
|
+
when DS9::ERR_BAD_CLIENT_MAGIC
|
120
|
+
GrpcKit.logger.error('Invalid client magic was received')
|
121
|
+
else
|
122
|
+
raise "#{e.message}. code=#{e.code}"
|
123
|
+
end
|
123
124
|
end
|
124
125
|
|
125
126
|
# `provider` for nghttp2_submit_response
|
@@ -164,7 +165,7 @@ module GrpcKit
|
|
164
165
|
# nghttp2 can't send any data once server sent actaul GoAway(not shutdown notice) frame.
|
165
166
|
# We want to send data in case of ClientStreamer or BidiBstreamer which they are sending data in same stream
|
166
167
|
# So we have to wait to send actual GoAway frame untill timeout or something
|
167
|
-
# @
|
168
|
+
# @drain_controller.recv_ping_ack
|
168
169
|
end
|
169
170
|
# when DS9::Frames::Goaway
|
170
171
|
# when DS9::Frames::RstStream
|
@@ -26,7 +26,7 @@ module GrpcKit
|
|
26
26
|
def send_msg(data, metadata: {}, last: false)
|
27
27
|
buf =
|
28
28
|
begin
|
29
|
-
@config.
|
29
|
+
@config.codec.encode(data)
|
30
30
|
rescue ArgumentError => e
|
31
31
|
raise GrpcKit::Errors::Internal, "Error while encoding in client: #{e}"
|
32
32
|
end
|
@@ -135,7 +135,7 @@ module GrpcKit
|
|
135
135
|
raise StopIteration if buf.nil?
|
136
136
|
|
137
137
|
begin
|
138
|
-
@config.
|
138
|
+
@config.codec.decode(buf)
|
139
139
|
rescue ArgumentError, TypeError => e
|
140
140
|
raise GrpcKit::Errors::Internal, "Error while decoding in Client: #{e}"
|
141
141
|
end
|
@@ -23,16 +23,16 @@ module GrpcKit
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# @param data [Object]
|
26
|
-
# @param
|
26
|
+
# @param codec [GrpcKit::Codec]
|
27
27
|
# @param last [Boolean]
|
28
28
|
# @param limit_size [Integer]
|
29
29
|
# @param initial_metadata [Hash<String,String>]
|
30
30
|
# @param trailing_metadata [Hash<String,String>]
|
31
31
|
# @return [void]
|
32
|
-
def send_msg(data,
|
32
|
+
def send_msg(data, codec, last: false, limit_size: nil, initial_metadata: {}, trailing_metadata: {})
|
33
33
|
buf =
|
34
34
|
begin
|
35
|
-
|
35
|
+
codec.encode(data)
|
36
36
|
rescue ArgumentError, TypeError => e
|
37
37
|
raise GrpcKit::Errors::Internal, "Error while encoding in server: #{e}"
|
38
38
|
end
|
@@ -51,11 +51,11 @@ module GrpcKit
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# @raise [StopIteration] when recving message finished
|
54
|
-
# @param
|
54
|
+
# @param codec [GrpcKit::Codec]
|
55
55
|
# @param last [Boolean]
|
56
56
|
# @param limit_size [Integer]
|
57
57
|
# @return [Object]
|
58
|
-
def recv_msg(
|
58
|
+
def recv_msg(codec, last: false, limit_size: nil)
|
59
59
|
data = @transport.read_data(last: last)
|
60
60
|
|
61
61
|
raise StopIteration if data.nil?
|
@@ -75,7 +75,7 @@ module GrpcKit
|
|
75
75
|
end
|
76
76
|
|
77
77
|
begin
|
78
|
-
|
78
|
+
codec.decode(buf)
|
79
79
|
rescue ArgumentError => e
|
80
80
|
raise GrpcKit::Errors::Internal, "Error while decoding in server: #{e}"
|
81
81
|
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.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Yuta Iwama
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-08 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.3.
|
19
|
+
version: 1.3.3
|
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.3.
|
26
|
+
version: 1.3.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: google-protobuf
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,6 +182,7 @@ files:
|
|
182
182
|
- lib/grpc_kit/calls/server_request_response.rb
|
183
183
|
- lib/grpc_kit/calls/server_server_streamer.rb
|
184
184
|
- lib/grpc_kit/client.rb
|
185
|
+
- lib/grpc_kit/codec.rb
|
185
186
|
- lib/grpc_kit/errors.rb
|
186
187
|
- lib/grpc_kit/grpc/core.rb
|
187
188
|
- lib/grpc_kit/grpc/dsl.rb
|
@@ -202,7 +203,6 @@ files:
|
|
202
203
|
- lib/grpc_kit/interceptors/server_request_response.rb
|
203
204
|
- lib/grpc_kit/interceptors/server_server_streamer.rb
|
204
205
|
- lib/grpc_kit/method_config.rb
|
205
|
-
- lib/grpc_kit/protobuffer.rb
|
206
206
|
- lib/grpc_kit/rpc_desc.rb
|
207
207
|
- lib/grpc_kit/rpcs.rb
|
208
208
|
- lib/grpc_kit/rpcs/client_bidi_streamer.rb
|
data/lib/grpc_kit/protobuffer.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GrpcKit
|
4
|
-
class ProtoBuffer
|
5
|
-
# @param encoder [Class, GrpcKit::GRPC::Stream]
|
6
|
-
# @param decoder [Class, GrpcKit::GRPC::Stream]
|
7
|
-
# @param encode_method [Symbol]
|
8
|
-
# @param decode_method [Symbol]
|
9
|
-
def initialize(encoder:, decoder:, encode_method:, decode_method:)
|
10
|
-
@encoder = encoder
|
11
|
-
@decoder = decoder
|
12
|
-
@encode_method = encode_method
|
13
|
-
@decode_method = decode_method
|
14
|
-
end
|
15
|
-
|
16
|
-
# @param data [String]
|
17
|
-
# @return [void]
|
18
|
-
def encode(data)
|
19
|
-
@encoder.send(@encode_method, data)
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param data [String]
|
23
|
-
# @return [void]
|
24
|
-
def decode(data)
|
25
|
-
@decoder.send(@decode_method, data)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|