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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -6
  3. data/examples/interceptors/client_logging_interceptor.rb +48 -0
  4. data/examples/interceptors/server_logging_interceptor.rb +44 -0
  5. data/examples/routeguide_client.rb +63 -3
  6. data/examples/routeguide_server.rb +86 -3
  7. data/grpc_kit.gemspec +1 -1
  8. data/lib/grpc.rb +1 -0
  9. data/lib/grpc_kit/client.rb +31 -79
  10. data/lib/grpc_kit/errors.rb +18 -8
  11. data/lib/grpc_kit/grpc/dsl.rb +19 -21
  12. data/lib/grpc_kit/grpc/generic_service.rb +1 -1
  13. data/lib/grpc_kit/grpc/interceptor.rb +57 -0
  14. data/lib/grpc_kit/grpc/logger.rb +17 -0
  15. data/lib/grpc_kit/interceptors.rb +11 -0
  16. data/lib/grpc_kit/interceptors/client_streamer.rb +31 -0
  17. data/lib/grpc_kit/interceptors/request_response.rb +70 -0
  18. data/lib/grpc_kit/interceptors/server_streamer.rb +33 -0
  19. data/lib/grpc_kit/interceptors/streaming.rb +70 -0
  20. data/lib/grpc_kit/method_config.rb +34 -0
  21. data/lib/grpc_kit/protobuffer.rb +20 -0
  22. data/lib/grpc_kit/rpc_desc.rb +103 -27
  23. data/lib/grpc_kit/rpcs.rb +11 -0
  24. data/lib/grpc_kit/rpcs/base.rb +30 -0
  25. data/lib/grpc_kit/rpcs/bidi_streamer.rb +18 -0
  26. data/lib/grpc_kit/rpcs/call.rb +27 -0
  27. data/lib/grpc_kit/rpcs/client_streamer.rb +38 -0
  28. data/lib/grpc_kit/rpcs/request_response.rb +50 -0
  29. data/lib/grpc_kit/rpcs/server_streamer.rb +42 -0
  30. data/lib/grpc_kit/server.rb +19 -38
  31. data/lib/grpc_kit/session/buffer.rb +58 -0
  32. data/lib/grpc_kit/session/client.rb +100 -52
  33. data/lib/grpc_kit/session/duration.rb +96 -0
  34. data/lib/grpc_kit/session/headers.rb +65 -0
  35. data/lib/grpc_kit/session/io.rb +56 -0
  36. data/lib/grpc_kit/session/server.rb +107 -68
  37. data/lib/grpc_kit/session/stream.rb +32 -40
  38. data/lib/grpc_kit/stream.rb +71 -0
  39. data/lib/grpc_kit/streams/client.rb +87 -0
  40. data/lib/grpc_kit/streams/packable.rb +60 -0
  41. data/lib/grpc_kit/streams/send_buffer.rb +48 -0
  42. data/lib/grpc_kit/streams/server.rb +36 -0
  43. data/lib/grpc_kit/streams/stream.rb +58 -0
  44. data/lib/grpc_kit/version.rb +1 -1
  45. metadata +32 -5
  46. data/lib/grpc_kit/io/basic.rb +0 -35
@@ -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}:#{details}")
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
- class Unimplemented < BadStatus
16
- def initialize(name)
17
- super(
18
- GrpcKit::StatusCodes::UNIMPLEMENTED,
19
- "Method not found at server: #{name}"
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
@@ -8,38 +8,37 @@ require 'grpc_kit/grpc/stream'
8
8
  module GrpcKit
9
9
  module GRPC
10
10
  module Dsl
11
- attr_accessor :service_name
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, input, output)
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 input.respond_to?(@marshal_class_method)
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 output.respond_to?(@unmarshal_class_method)
27
+ unless unmarshal.respond_to?(@unmarshal_class_method)
30
28
  raise "#{unmarshal} must implement #{unmarshal}.#{@unmarshal_class_method}"
31
29
  end
32
30
 
33
- # create StreamDesc?
34
- rpc_descs[name] = GrpcKit::RpcDesc.new(
31
+ rpc_desc = GrpcKit::RpcDesc.new(
35
32
  name: name,
36
- input: input,
37
- output: output,
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(rpc_descs[name].ruby_style_name) do |_, _|
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_.each_pair do |_, rpc_desc|
53
+ rpc_descs_.each do |_, rpc_desc|
56
54
  method_name = rpc_desc.ruby_style_name
57
- path = rpc_desc.path(service_name_)
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(path, request, rpc_desc, opts)
59
+ request_response(rpc, request, opts)
62
60
  end
63
61
  elsif rpc_desc.client_streamer?
64
- define_method(method_name) do |requests, opts = {}|
65
- client_streamer(path, requests, rpc_desc, opts)
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 = {}, &blk|
69
- server_streamer(path, request, rpc_desc, opts, &blk)
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(path, requests, rpc_desc, opts, &blk)
71
+ bidi_streamer(rpc, requests, opts, &blk)
74
72
  end
75
73
  else
76
74
  raise "unknown #{rpc_desc}"
@@ -7,8 +7,8 @@ module GrpcKit
7
7
  module GenericService
8
8
  def self.included(obj)
9
9
  obj.extend(GrpcKit::GRPC::Dsl)
10
- return unless obj.service_name.nil?
11
10
 
11
+ # return unless obj.service_name.nil?
12
12
  # if obj.name.nil?
13
13
  # obj.service_name = 'GenericService'
14
14
  # else
@@ -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,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GrpcKit
4
+ module GRPC
5
+ module DefaultLogger
6
+ def self.logger
7
+ LOGGER
8
+ end
9
+
10
+ LOGGER = Logger.new(STDOUT)
11
+ end
12
+
13
+ unless methods.include?(:logger)
14
+ extend DefaultLogger
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'grpc_kit/interceptors/request_response'
4
+ require 'grpc_kit/interceptors/server_streamer'
5
+ require 'grpc_kit/interceptors/client_streamer'
6
+ # TODO: bidi
7
+
8
+ module GrpcKit
9
+ module Interceptors
10
+ end
11
+ 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