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.
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