grpc_kit 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +0 -3
  4. data/examples/interceptors/call_stream.rb +5 -0
  5. data/grpc_kit.gemspec +2 -2
  6. data/lib/grpc.rb +1 -1
  7. data/lib/grpc_kit/call.rb +1 -1
  8. data/lib/grpc_kit/calls/server_bidi_streamer.rb +2 -2
  9. data/lib/grpc_kit/calls/server_client_streamer.rb +2 -2
  10. data/lib/grpc_kit/calls/server_request_response.rb +2 -2
  11. data/lib/grpc_kit/calls/server_server_streamer.rb +2 -2
  12. data/lib/grpc_kit/client.rb +1 -1
  13. data/lib/grpc_kit/codec.rb +28 -0
  14. data/lib/grpc_kit/errors.rb +10 -9
  15. data/lib/grpc_kit/grpc/core.rb +1 -1
  16. data/lib/grpc_kit/grpc/dsl.rb +5 -5
  17. data/lib/grpc_kit/grpc/errors.rb +1 -1
  18. data/lib/grpc_kit/grpc/generic_service.rb +2 -2
  19. data/lib/grpc_kit/grpc/interceptor.rb +1 -1
  20. data/lib/grpc_kit/grpc/logger.rb +1 -1
  21. data/lib/grpc_kit/grpc/stream.rb +1 -1
  22. data/lib/grpc_kit/interceptor_registory.rb +2 -2
  23. data/lib/grpc_kit/interceptors/client_bidi_streamer.rb +1 -1
  24. data/lib/grpc_kit/interceptors/client_client_streamer.rb +1 -1
  25. data/lib/grpc_kit/interceptors/client_request_response.rb +1 -1
  26. data/lib/grpc_kit/interceptors/client_server_streamer.rb +1 -1
  27. data/lib/grpc_kit/interceptors/server_bidi_streamer.rb +1 -1
  28. data/lib/grpc_kit/interceptors/server_client_streamer.rb +1 -1
  29. data/lib/grpc_kit/interceptors/server_request_response.rb +1 -1
  30. data/lib/grpc_kit/interceptors/server_server_streamer.rb +1 -1
  31. data/lib/grpc_kit/interceptors.rb +2 -2
  32. data/lib/grpc_kit/method_config.rb +5 -5
  33. data/lib/grpc_kit/rpc_desc.rb +24 -24
  34. data/lib/grpc_kit/rpcs.rb +1 -1
  35. data/lib/grpc_kit/server.rb +29 -24
  36. data/lib/grpc_kit/session/client_session.rb +17 -5
  37. data/lib/grpc_kit/session/drain_controller.rb +40 -16
  38. data/lib/grpc_kit/session/server_session.rb +15 -14
  39. data/lib/grpc_kit/stream/client_stream.rb +2 -2
  40. data/lib/grpc_kit/stream/server_stream.rb +6 -6
  41. data/lib/grpc_kit/version.rb +1 -1
  42. metadata +6 -6
  43. data/lib/grpc_kit/protobuffer.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb504e4e1ba14e8e0a411336254cd5f7b3b20a39305cc31e506ae4d0d81cd77a
4
- data.tar.gz: 2595cda7ac23058f72e76e0e8955b70d305c585fe34d63e1bd183d1fc40c104e
3
+ metadata.gz: 669ad89bc39849c66aeea640ba77ac6204e7cb1c2034a77b4bd4b698830c071a
4
+ data.tar.gz: fa4a14c0c2bf93837826b9477c126031849e95310f18f7633237d9a485688e56
5
5
  SHA512:
6
- metadata.gz: f00be6d6aace37b66fa123f50b89903998b6520446369e067dc56afc4342b1d62153f15f631f170fb0aed6b0dba27f0db270d94edd78ad7ccd5f712eb0163b5b
7
- data.tar.gz: 83671c633699f7a0e49adbfffbf9fe383a7eae57216d7876760b9bbd6114018cf606183420135807406ece0ebbbd6fdb6a5fd251956b5e1cd59adef6c68f4369
6
+ metadata.gz: c20fe45fbc01d727fdde2f70d1ebd53bcd2c89c03e9ef01e676a73344e7618aa7e32eaa07af71b10733cb79986fd1883647ba81a5e71b04779a8ded3c4bd8c4a
7
+ data.tar.gz: be9fb063cd523f9c6c2a47a58584a930f431378a050af865106126b1784ace126291d226c088884c7bd479423d86076439189856e7831341a1b22d7465443043
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 ganmacs
3
+ Copyright (c) 2019 Yuta Iwama
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -71,6 +71,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ganmac
71
71
 
72
72
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
73
73
 
74
- ## Code of Conduct
75
-
76
- TODO
@@ -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 = ['ganmacs']
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.1'
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
@@ -3,4 +3,4 @@
3
3
  # Compatible file for xx_services_pb.rb and xx_pb.rb which are created by grpc-tools gem
4
4
  require 'grpc_kit'
5
5
 
6
- GRPC = GrpcKit::GRPC
6
+ GRPC = GrpcKit::Grpc
data/lib/grpc_kit/call.rb CHANGED
@@ -26,7 +26,7 @@ module GrpcKit
26
26
  @metadata = metadata
27
27
  @method_name = @config.method_name
28
28
  @service_name = @config.service_name
29
- @protobuf = @config.protobuf
29
+ @codec = @config.codec
30
30
  @timeout = timeout
31
31
  @stream = stream
32
32
 
@@ -23,7 +23,7 @@ module GrpcKit
23
23
  def send_msg(data)
24
24
  @stream.send_msg(
25
25
  data,
26
- @protobuf,
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(@protobuf, limit_size: @config.max_receive_message_size)
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
- @protobuf,
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(@protobuf, limit_size: @config.max_receive_message_size)
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
- @protobuf,
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(@protobuf, last: true, limit_size: @config.max_receive_message_size)
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
- @protobuf,
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(@protobuf, last: true, limit_size: @config.max_receive_message_size)
33
+ @stream.recv_msg(@codec, last: true, limit_size: @config.max_receive_message_size)
34
34
  end
35
35
  end
36
36
  end
@@ -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::GRPC::ClientInterceptor>] list of interceptors
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
@@ -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
- CODES.fetch(code).new(message)
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,
@@ -3,7 +3,7 @@
3
3
  require 'grpc_kit/status_codes'
4
4
 
5
5
  module GrpcKit
6
- module GRPC
6
+ module Grpc
7
7
  module Core
8
8
  StatusCodes = GrpcKit::StatusCodes
9
9
  end
@@ -6,7 +6,7 @@ require 'grpc_kit/client'
6
6
  require 'grpc_kit/grpc/stream'
7
7
 
8
8
  module GrpcKit
9
- module GRPC
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::GRPC::Stream] marshaling object
27
- # @param unmarshal [Class, GrpcKit::GRPC::Stream] unmarshaling object
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::GRPC::Stream]
58
+ # @return [GrpcKit::Grpc::Stream]
59
59
  def stream(cls)
60
- GrpcKit::GRPC::Stream.new(cls)
60
+ GrpcKit::Grpc::Stream.new(cls)
61
61
  end
62
62
 
63
63
  # @return [GrpcKit::Client]
@@ -4,7 +4,7 @@ require 'grpc_kit'
4
4
  require 'grpc_kit/errors'
5
5
 
6
6
  module GrpcKit
7
- module GRPC
7
+ module Grpc
8
8
  include GrpcKit::Errors
9
9
  end
10
10
  end
@@ -3,10 +3,10 @@
3
3
  require 'grpc_kit/grpc/dsl'
4
4
 
5
5
  module GrpcKit
6
- module GRPC
6
+ module Grpc
7
7
  module GenericService
8
8
  def self.included(obj)
9
- obj.extend(GrpcKit::GRPC::Dsl)
9
+ obj.extend(GrpcKit::Grpc::Dsl)
10
10
  end
11
11
  end
12
12
  end
@@ -3,7 +3,7 @@
3
3
  require 'grpc_kit/grpc/dsl'
4
4
 
5
5
  module GrpcKit
6
- module GRPC
6
+ module Grpc
7
7
  class Interceptor
8
8
  def initialize(options = {})
9
9
  @options = options
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrpcKit
4
- module GRPC
4
+ module Grpc
5
5
  module DefaultLogger
6
6
  def logger
7
7
  GrpcKit.logger
@@ -4,7 +4,7 @@ require 'grpc_kit/grpc/dsl'
4
4
  require 'forwardable'
5
5
 
6
6
  module GrpcKit
7
- module GRPC
7
+ module Grpc
8
8
  class Stream
9
9
  extend Forwardable
10
10
  delegate %i[encode decode] => :@klass
@@ -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::GRPC::Interceptor)
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::GRPC::Interceptor}"
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::GRPC::ClientInterceptor]
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::GRPC::ClientInterceptor]
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::GRPC::ClientInterceptor>]
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::GRPC::ClientInterceptor]
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::GRPC::ServerInterceptor]
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::GRPC::ServerInterceptor]
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::GRPC::ServerInterceptor>]
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::GRPC::ServerInterceptor]
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::GRPC::ClientInterceptor>]
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::GRPC::ServerInterceptor>]
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
- :protobuf,
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:, protobuf:, service_name:, method_name:, interceptor:,
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, protobuf, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
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:, protobuf:, service_name:, method_name:, interceptor:,
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, protobuf, interceptor, service_name, method_name, max_receive_message_size, max_send_message_size, compressor_type)
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'grpc_kit/method_config'
4
- require 'grpc_kit/protobuffer'
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::GRPC::Stream] marshaling object
28
- # @param unmarshal [Class, GrpcKit::GRPC::Stream] unmarshaling object
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::GRPC::GenericService]
42
- # @param interceptors [Array<GrpcKit::GRPC::ServerInterceptor>]
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
- protobuf: server_protobuf,
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::GRPC::ClientInterceptor>]
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
- protobuf: client_protobuf,
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::GRPC::Stream) && !@unmarshal.is_a?(GrpcKit::GRPC::Stream)
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::GRPC::Stream) && !@unmarshal.is_a?(GrpcKit::GRPC::Stream)
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::GRPC::Stream) && @unmarshal.is_a?(GrpcKit::GRPC::Stream)
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::GRPC::Stream) && @unmarshal.is_a?(GrpcKit::GRPC::Stream)
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 server_protobuf
133
- @server_protobuf ||= ProtoBuffer.new(
134
- encoder: @unmarshal,
135
- decoder: @marshal,
136
- encode_method: @marshal_method,
137
- decode_method: @unmarshal_method,
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 client_protobuf
142
- @client_protobuf ||= ProtoBuffer.new(
143
- encoder: @marshal,
144
- decoder: @unmarshal,
145
- encode_method: @marshal_method,
146
- decode_method: @unmarshal_method,
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
@@ -19,7 +19,7 @@ module GrpcKit
19
19
  end
20
20
 
21
21
  class ServerRpc
22
- # @param handler [GrpcKit::GRPC::GenericService]
22
+ # @param handler [GrpcKit::Grpc::GenericService]
23
23
  # @param config [GrpcKit::MethodConfig]
24
24
  def initialize(handler, config)
25
25
  @handler = handler
@@ -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::GRPC::ServerInterceptor>] list of interceptors
9
- def initialize(interceptors: [])
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::GRPC::GenericService] gRPC handler object or class
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::GRPC::GenericService)
25
- raise "#{klass} must include GRPC::GenericService"
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
- Thread.new do
53
- @mutex.synchronize do
54
- GrpcKit.logger.debug('force shutdown')
55
- @stopping = true
56
- @sessions.each(&:shutdown)
57
- end
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
- sleep 1
75
- end
70
+ end_time = Time.now + @shutdown_timeout
71
+ until end_time < Time.now
72
+ if @sessions.empty?
73
+ return
76
74
  end
77
- rescue Timeout::Error => _
78
- GrpcKit.logger.debug('Max wait time expired')
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 want_read?
71
- do_read
72
- end
72
+ if @no_write_data
73
+ @io.wait_readable
73
74
 
74
- if want_write?
75
- send
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
- @sent_shutdown_notice = false
10
- @goaway_sent = false
11
- @after_one_rtt = false
12
- # @sent_ping = false
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
- @after_one_rtt = true
30
+ if @status == Status::SENT_PING
31
+ next_step
32
+ end
18
33
  end
19
34
 
20
35
  # @return [void]
21
- def call(session)
22
- if @goaway_sent
23
- # session.shutdown
24
- elsif @sent_shutdown_notice && @after_one_rtt
25
- session.submit_goaway(DS9::NO_ERROR, session.last_proc_stream_id)
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
- @sent_shutdown_notice = true
32
- session.submit_ping # wait for 1 RTT
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
- @drain = nil
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 @peer_shutdowned || @stop || !(want_read? || want_write?)
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 @drain
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
- @drain.call(self)
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
- @drain ||= GrpcKit::Session::DrainController.new
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
- raise e
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
- # @drain.recv_ping_ack if @drain
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.protobuf.encode(data)
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.protobuf.decode(buf)
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 protobuf [GrpcKit::ProtoBuffer]
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, protobuf, last: false, limit_size: nil, initial_metadata: {}, trailing_metadata: {})
32
+ def send_msg(data, codec, last: false, limit_size: nil, initial_metadata: {}, trailing_metadata: {})
33
33
  buf =
34
34
  begin
35
- protobuf.encode(data)
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 protobuf [GrpcKit::ProtoBuffer]
54
+ # @param codec [GrpcKit::Codec]
55
55
  # @param last [Boolean]
56
56
  # @param limit_size [Integer]
57
57
  # @return [Object]
58
- def recv_msg(protobuf, last: false, limit_size: nil)
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
- protobuf.decode(buf)
78
+ codec.decode(buf)
79
79
  rescue ArgumentError => e
80
80
  raise GrpcKit::Errors::Internal, "Error while decoding in server: #{e}"
81
81
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrpcKit
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
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.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
- - ganmacs
7
+ - Yuta Iwama
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-20 00:00:00.000000000 Z
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.1
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.1
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
@@ -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