grpc_kit 0.1.0 → 0.1.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/.rubocop.yml +22 -6
- data/examples/interceptors/client_logging_interceptor.rb +48 -0
- data/examples/interceptors/server_logging_interceptor.rb +44 -0
- data/examples/routeguide_client.rb +63 -3
- data/examples/routeguide_server.rb +86 -3
- data/grpc_kit.gemspec +1 -1
- data/lib/grpc.rb +1 -0
- data/lib/grpc_kit/client.rb +31 -79
- data/lib/grpc_kit/errors.rb +18 -8
- data/lib/grpc_kit/grpc/dsl.rb +19 -21
- data/lib/grpc_kit/grpc/generic_service.rb +1 -1
- data/lib/grpc_kit/grpc/interceptor.rb +57 -0
- data/lib/grpc_kit/grpc/logger.rb +17 -0
- data/lib/grpc_kit/interceptors.rb +11 -0
- data/lib/grpc_kit/interceptors/client_streamer.rb +31 -0
- data/lib/grpc_kit/interceptors/request_response.rb +70 -0
- data/lib/grpc_kit/interceptors/server_streamer.rb +33 -0
- data/lib/grpc_kit/interceptors/streaming.rb +70 -0
- data/lib/grpc_kit/method_config.rb +34 -0
- data/lib/grpc_kit/protobuffer.rb +20 -0
- data/lib/grpc_kit/rpc_desc.rb +103 -27
- data/lib/grpc_kit/rpcs.rb +11 -0
- data/lib/grpc_kit/rpcs/base.rb +30 -0
- data/lib/grpc_kit/rpcs/bidi_streamer.rb +18 -0
- data/lib/grpc_kit/rpcs/call.rb +27 -0
- data/lib/grpc_kit/rpcs/client_streamer.rb +38 -0
- data/lib/grpc_kit/rpcs/request_response.rb +50 -0
- data/lib/grpc_kit/rpcs/server_streamer.rb +42 -0
- data/lib/grpc_kit/server.rb +19 -38
- data/lib/grpc_kit/session/buffer.rb +58 -0
- data/lib/grpc_kit/session/client.rb +100 -52
- data/lib/grpc_kit/session/duration.rb +96 -0
- data/lib/grpc_kit/session/headers.rb +65 -0
- data/lib/grpc_kit/session/io.rb +56 -0
- data/lib/grpc_kit/session/server.rb +107 -68
- data/lib/grpc_kit/session/stream.rb +32 -40
- data/lib/grpc_kit/stream.rb +71 -0
- data/lib/grpc_kit/streams/client.rb +87 -0
- data/lib/grpc_kit/streams/packable.rb +60 -0
- data/lib/grpc_kit/streams/send_buffer.rb +48 -0
- data/lib/grpc_kit/streams/server.rb +36 -0
- data/lib/grpc_kit/streams/stream.rb +58 -0
- data/lib/grpc_kit/version.rb +1 -1
- metadata +32 -5
- data/lib/grpc_kit/io/basic.rb +0 -35
data/lib/grpc_kit/errors.rb
CHANGED
@@ -7,18 +7,28 @@ module GrpcKit
|
|
7
7
|
# https://github.com/grpc/grpc/blob/23b5b1a5a9c7084c5b64d4998ee15af0f77bd589/doc/statuscodes.md
|
8
8
|
class BadStatus < StandardError
|
9
9
|
def initialize(code, message)
|
10
|
-
super("#{code}
|
10
|
+
super("#{code} #{message}")
|
11
11
|
@code = code
|
12
12
|
@message = message
|
13
13
|
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class DeadlienExceeded < BadStatus
|
17
|
+
def initialize(msg)
|
18
|
+
super(
|
19
|
+
GrpcKit::StatusCodes::DEADLINE_EXCEEDED,
|
20
|
+
msg.to_s,
|
21
|
+
# "Deadline expires before server returns status: #{msg}"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
14
25
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
26
|
+
class Unimplemented < BadStatus
|
27
|
+
def initialize(name)
|
28
|
+
super(
|
29
|
+
GrpcKit::StatusCodes::UNIMPLEMENTED,
|
30
|
+
"Method not found at server: #{name}"
|
31
|
+
)
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
data/lib/grpc_kit/grpc/dsl.rb
CHANGED
@@ -8,38 +8,37 @@ require 'grpc_kit/grpc/stream'
|
|
8
8
|
module GrpcKit
|
9
9
|
module GRPC
|
10
10
|
module Dsl
|
11
|
-
|
12
|
-
|
13
|
-
attr_writer :marshal_class_method, :unmarshal_class_method
|
11
|
+
attr_writer :service_name, :marshal_class_method, :unmarshal_class_method
|
14
12
|
|
15
13
|
def inherited(subclass)
|
16
14
|
subclass.rpc_descs.merge!(rpc_descs)
|
17
|
-
subclass.service_name = service_name
|
15
|
+
subclass.service_name = @service_name
|
18
16
|
end
|
19
17
|
|
20
|
-
def rpc(name,
|
18
|
+
def rpc(name, marshal, unmarshal)
|
21
19
|
if rpc_descs.key?(name)
|
22
20
|
raise "rpc (#{name}) is already defined"
|
23
21
|
end
|
24
22
|
|
25
|
-
unless
|
23
|
+
unless marshal.respond_to?(@marshal_class_method)
|
26
24
|
raise "#{marshal} must implement #{marshal}.#{@marshal_class_method}"
|
27
25
|
end
|
28
26
|
|
29
|
-
unless
|
27
|
+
unless unmarshal.respond_to?(@unmarshal_class_method)
|
30
28
|
raise "#{unmarshal} must implement #{unmarshal}.#{@unmarshal_class_method}"
|
31
29
|
end
|
32
30
|
|
33
|
-
|
34
|
-
rpc_descs[name] = GrpcKit::RpcDesc.new(
|
31
|
+
rpc_desc = GrpcKit::RpcDesc.new(
|
35
32
|
name: name,
|
36
|
-
|
37
|
-
|
33
|
+
marshal: marshal,
|
34
|
+
unmarshal: unmarshal,
|
38
35
|
marshal_method: @marshal_class_method,
|
39
36
|
unmarshal_method: @unmarshal_class_method,
|
37
|
+
service_name: @service_name,
|
40
38
|
)
|
39
|
+
rpc_descs[rpc_desc.path] = rpc_desc
|
41
40
|
|
42
|
-
define_method(
|
41
|
+
define_method(rpc_desc.ruby_style_name) do |_, _|
|
43
42
|
raise GrpcKit::Errors::Unimplemented, name.to_s
|
44
43
|
end
|
45
44
|
end
|
@@ -50,27 +49,26 @@ module GrpcKit
|
|
50
49
|
|
51
50
|
def rpc_stub_class
|
52
51
|
rpc_descs_ = rpc_descs
|
53
|
-
service_name_ = service_name
|
54
52
|
Class.new(GrpcKit::Client) do
|
55
|
-
rpc_descs_.
|
53
|
+
rpc_descs_.each do |_, rpc_desc|
|
56
54
|
method_name = rpc_desc.ruby_style_name
|
57
|
-
|
55
|
+
rpc = rpc_desc.build_client
|
58
56
|
|
59
57
|
if rpc_desc.request_response?
|
60
58
|
define_method(method_name) do |request, opts = {}|
|
61
|
-
request_response(
|
59
|
+
request_response(rpc, request, opts)
|
62
60
|
end
|
63
61
|
elsif rpc_desc.client_streamer?
|
64
|
-
define_method(method_name) do |
|
65
|
-
client_streamer(
|
62
|
+
define_method(method_name) do |opts = {}|
|
63
|
+
client_streamer(rpc, opts)
|
66
64
|
end
|
67
65
|
elsif rpc_desc.server_streamer?
|
68
|
-
define_method(method_name) do |request, opts = {}
|
69
|
-
server_streamer(
|
66
|
+
define_method(method_name) do |request, opts = {}|
|
67
|
+
server_streamer(rpc, request, opts)
|
70
68
|
end
|
71
69
|
elsif rpc_desc.bidi_streamer?
|
72
70
|
define_method(method_name) do |requests, opts = {}, &blk|
|
73
|
-
bidi_streamer(
|
71
|
+
bidi_streamer(rpc, requests, opts, &blk)
|
74
72
|
end
|
75
73
|
else
|
76
74
|
raise "unknown #{rpc_desc}"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/grpc/dsl'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
module GRPC
|
7
|
+
class Interceptor
|
8
|
+
def initialize(options = {})
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ClientInterceptor < Interceptor
|
14
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
15
|
+
|
16
|
+
def request_response(request: nil, call: nil, method: nil, metadata: nil)
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
def client_streamer(requests: nil, call: nil, method: nil, metadata: nil)
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
|
24
|
+
def server_streamer(request: nil, call: nil, method: nil, metadata: nil)
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
def bidi_streamer(requests: nil, call: nil, method: nil, metadata: nil)
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
|
32
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
33
|
+
end
|
34
|
+
|
35
|
+
class ServerInterceptor < Interceptor
|
36
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
37
|
+
|
38
|
+
def request_response(request: nil, call: nil, method: nil)
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
def client_streamer(call: nil, method: nil)
|
43
|
+
yield
|
44
|
+
end
|
45
|
+
|
46
|
+
def server_streamer(request: nil, call: nil, method: nil)
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
|
50
|
+
def bidi_streamer(requests: nil, call: nil, method: nil)
|
51
|
+
yield
|
52
|
+
end
|
53
|
+
|
54
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/interceptors/streaming'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
module Interceptors
|
7
|
+
module Client
|
8
|
+
class ClientStreamer < Streaming
|
9
|
+
private
|
10
|
+
|
11
|
+
def invoke(interceptor, call)
|
12
|
+
# We don't need a `:requests` parameter but,
|
13
|
+
# it shuoldn't remove from paramters due to having a compatibility of grpc gem.
|
14
|
+
interceptor.client_streamer(requests: nil, call: call, method: call.method, metadata: nil) do |s|
|
15
|
+
yield(s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Server
|
22
|
+
class ClientStreamer < Streaming
|
23
|
+
def invoke(interceptor, call)
|
24
|
+
interceptor.client_streamer(call: call, method: call.method) do |s|
|
25
|
+
yield(s)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
module Interceptors
|
5
|
+
module Client
|
6
|
+
class RequestResponse
|
7
|
+
attr_writer :interceptors
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Cant' get interceptor at definition time...
|
11
|
+
@interceptors = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def intercept(request, call, metadata, &block)
|
15
|
+
if @interceptors && !@interceptors.empty?
|
16
|
+
do_intercept(@interceptors.dup, request, call, metadata, &block)
|
17
|
+
else
|
18
|
+
yield(request, call, metadata)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def do_intercept(interceptors, request, call, metadata)
|
25
|
+
if interceptors.empty?
|
26
|
+
return yield(request, call, metadata)
|
27
|
+
end
|
28
|
+
|
29
|
+
interceptor = interceptors.pop
|
30
|
+
interceptor.request_response(request: request, call: call, method: call.method, metadata: metadata) do
|
31
|
+
do_intercept(interceptors, request, call, metadata) do |r, c, m|
|
32
|
+
yield(r, c, m)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Server
|
40
|
+
class RequestResponse
|
41
|
+
def initialize(interceptors)
|
42
|
+
@interceptors = interceptors
|
43
|
+
end
|
44
|
+
|
45
|
+
def intercept(request, call, &block)
|
46
|
+
if @interceptors && !@interceptors.empty?
|
47
|
+
do_intercept(@interceptors.dup, request, call, &block)
|
48
|
+
else
|
49
|
+
yield(request, call)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def do_intercept(interceptors, request, call)
|
56
|
+
if interceptors.empty?
|
57
|
+
return yield(request, call)
|
58
|
+
end
|
59
|
+
|
60
|
+
interceptor = interceptors.pop
|
61
|
+
interceptor.request_response(request: request, call: call, method: call.method) do
|
62
|
+
do_intercept(interceptors, request, call) do |req, c|
|
63
|
+
yield(req, c)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/interceptors/streaming'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
module Interceptors
|
7
|
+
module Client
|
8
|
+
class ServerStreamer < Streaming
|
9
|
+
private
|
10
|
+
|
11
|
+
def invoke(interceptor, call)
|
12
|
+
# We don't need a `:request` parameter but,
|
13
|
+
# it shuoldn't remove from paramters due to having a compatibility of grpc gem.
|
14
|
+
interceptor.server_streamer(request: nil, call: call, method: call.method, metadata: nil) do |s|
|
15
|
+
yield(s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Server
|
22
|
+
class ServerStreamer < Streaming
|
23
|
+
def invoke(interceptor, call)
|
24
|
+
# We don't need a `:request` parameter but,
|
25
|
+
# it shuoldn't remove from paramters due to having a compatibility of grpc gem.
|
26
|
+
interceptor.server_streamer(request: nil, call: call, method: call.method) do |s|
|
27
|
+
yield(s)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
module Interceptors
|
5
|
+
module Client
|
6
|
+
class Streaming
|
7
|
+
attr_writer :interceptors
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Cant' get interceptor at definition time...
|
11
|
+
@interceptors = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def intercept(call, &block)
|
15
|
+
if @interceptors && !@interceptors.empty?
|
16
|
+
do_intercept(@interceptors.dup, call, &block)
|
17
|
+
else
|
18
|
+
yield(call)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def do_intercept(interceptors, call)
|
25
|
+
if interceptors.empty?
|
26
|
+
return yield(call)
|
27
|
+
end
|
28
|
+
|
29
|
+
interceptor = interceptors.pop
|
30
|
+
invoke(interceptor, call) do |inter_call|
|
31
|
+
do_intercept(interceptors, inter_call) do |c|
|
32
|
+
yield(c)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Server
|
40
|
+
class Streaming
|
41
|
+
def initialize(interceptors)
|
42
|
+
@interceptors = interceptors
|
43
|
+
end
|
44
|
+
|
45
|
+
def intercept(call, &block)
|
46
|
+
if @interceptors && !@interceptors.empty?
|
47
|
+
do_intercept(@interceptors.dup, call, &block)
|
48
|
+
else
|
49
|
+
yield(call)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def do_intercept(interceptors, call)
|
56
|
+
if interceptors.empty?
|
57
|
+
return yield(call)
|
58
|
+
end
|
59
|
+
|
60
|
+
interceptor = interceptors.pop
|
61
|
+
invoke(interceptor, call) do |inter_call|
|
62
|
+
do_intercept(interceptors, inter_call) do |c|
|
63
|
+
yield(c)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrpcKit
|
4
|
+
MethodConfig = Struct.new(
|
5
|
+
:path,
|
6
|
+
:ruby_style_method_name,
|
7
|
+
:protobuf,
|
8
|
+
:interceptor,
|
9
|
+
:service_name,
|
10
|
+
:method_name,
|
11
|
+
:max_receive_message_size,
|
12
|
+
:max_send_message_size,
|
13
|
+
:compressor_type,
|
14
|
+
) do
|
15
|
+
MAX_SERVER_RECEIVE_MESSAGE_SIZE = 1024 * 1024 * 4
|
16
|
+
MAX_SERVER_SEND_MESSAGE_SIZE = 1024 * 1024 * 4
|
17
|
+
MAX_CLIENT_RECEIVE_MESSAGE_SIZE = 1024 * 1024 * 4
|
18
|
+
MAX_CLIENT_SEND_MESSAGE_SIZE = 1024 * 1024 * 4
|
19
|
+
|
20
|
+
def self.build_for_server(
|
21
|
+
path:, ruby_style_method_name:, protobuf:, service_name:, method_name:, interceptor:,
|
22
|
+
max_receive_message_size: MAX_SERVER_RECEIVE_MESSAGE_SIZE, max_send_message_size: MAX_SERVER_SEND_MESSAGE_SIZE, compressor_type: ''
|
23
|
+
)
|
24
|
+
new(path, ruby_style_method_name, protobuf, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.build_for_client(
|
28
|
+
path:, ruby_style_method_name:, protobuf:, service_name:, method_name:, interceptor:,
|
29
|
+
max_receive_message_size: MAX_CLIENT_RECEIVE_MESSAGE_SIZE, max_send_message_size: MAX_CLIENT_SEND_MESSAGE_SIZE, compressor_type: ''
|
30
|
+
)
|
31
|
+
new(path, ruby_style_method_name, protobuf, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|