grpc_kit 0.2.0 → 0.2.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 (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