grpc_kit 0.2.0 → 0.2.1
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/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
|