grpc_kit 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|