gruf 2.2.2 → 2.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0e7891457a5fc0c9540a5347060adb81d943c2f
4
- data.tar.gz: b6f8e81ec7ad9fda50874fd0dfc34493dd2fabce
3
+ metadata.gz: d13a8ed53bfc2a83d33c7ca8eed57d302019d9b7
4
+ data.tar.gz: c665d27586c8c446071275b1490c6814391e7f49
5
5
  SHA512:
6
- metadata.gz: 7881d0383409066521a069f99d1a978c67c281a6142eef378e7204dcb394fd7d3e53d0a82453bc36097e611fada3daded6bc6c91a7697a7e924bcbbbef2f6a2f
7
- data.tar.gz: 6748606577097d0b5bf6cec7c4afe6254b71f3abd39b40a3a3ca1dde6ac43f43cb592fe14c83e51158e1929f25cb4e442cf2b2afe00f759332fe404558fee6e5
6
+ metadata.gz: 18b6a5bb4cc864ec8f9dd66428fd08843d71b27a5c61706f4d352e2554644b9e9062e37c8e165917c021cc1970560099920e8f7f3be0149f60b18fa35e86c02c
7
+ data.tar.gz: 6432ce2af8567422c3ee0dce084bac1f6100536421f4f93cfee554dd78384f989ac163247d81a52c3043123d06a4e841337198bb9e6a4cf2ce4dbdf36410cce2
@@ -2,9 +2,15 @@ Changelog for the gruf gem. This includes internal history before the gem was ma
2
2
 
3
3
  ### Pending release
4
4
 
5
+ ### 2.3.0
6
+
7
+ - Add Gruf::Interceptors::ClientInterceptor for intercepting outbound client calls
8
+ - Add command-line arguments to the gruf binstub
9
+ - Add ability to specify server hostname via CLI argument
10
+
5
11
  ### 2.2.2
6
12
 
7
- - Added ignore_methods option for RequestLogging interceptor [#45]
13
+ - Add ignore_methods option for RequestLogging interceptor [#45]
8
14
 
9
15
  ### 2.2.1
10
16
 
data/README.md CHANGED
@@ -72,6 +72,39 @@ end
72
72
 
73
73
  Note this returns a response object. The response object can provide `trailing_metadata` as well as a `execution_time`.
74
74
 
75
+ ### Client Interceptors
76
+
77
+ Gruf comes with an assistance class for client interceptors that you can use - or you can use the native gRPC core
78
+ interceptors. Either way, you pass them into the client_options when creating a client:
79
+
80
+ ```ruby
81
+ class MyInterceptor < Gruf::Interceptors::ClientInterceptor
82
+ def call(request_context:)
83
+ logger.info "Got method #{request_context.method}!"
84
+ yield
85
+ end
86
+ end
87
+
88
+ ::Gruf::Client.new(
89
+ service: ::Demo::ThingService,
90
+ client_options: [
91
+ interceptors: [MyInterceptor.new]
92
+ ])
93
+ ```
94
+
95
+ The `interceptors` option in `client_options` can accept either a `GRPC::ClientInterceptor` class or a
96
+ `Gruf::Interceptors::ClientInterceptor`, since the latter just extends the former. The gruf client interceptors
97
+ take an optional alternative approach: rather than having separate methods for each request type, it provides a default
98
+ `call` method that passes in a `RequestContext` object, which has the following attributes:
99
+
100
+ * *type* - A Symbol of the type of request (`request_response`, `server_streamer`, etc)
101
+ * *requests* An enumerable of requests being sent. For unary requests, this is a single request in an array
102
+ * *call* - The `GRPC::ActiveCall` object
103
+ * *method* - The Method being called
104
+ * *metadata* - The hash of outgoing metadata
105
+
106
+ Note that you _must_ yield back the block when building a client interceptor, so that the call can be executed.
107
+
75
108
  ### Server
76
109
 
77
110
  Add an initializer:
@@ -133,6 +166,21 @@ Finally, you can start the server by running:
133
166
  bundle exec gruf
134
167
  ```
135
168
 
169
+ ### Command-Line Options
170
+
171
+ Gruf comes baked in with a few command-line options for the binstub:
172
+
173
+ | Option | Description |
174
+ | ------ | ----------- |
175
+ | -h, --help | Displays the help message |
176
+ | -v, --version | Displays the gruf version |
177
+ | --host | Specify the server binding host |
178
+ | --suppress-default-interceptors | Do not use the default interceptors for the server |
179
+ | --backtrace-on-error | Push backtraces on exceptions to the error serializer |
180
+
181
+ These options will override whatever is passed in the Gruf configure block or
182
+ initializer.
183
+
136
184
  ### Basic Authentication
137
185
 
138
186
  Gruf comes packaged in with a Basic Authentication interceptor. It takes in an array of supported
@@ -370,12 +418,9 @@ view and clone that shows how to integrate Gruf into an existing Rails applicati
370
418
 
371
419
  ### Gruf 3.0
372
420
 
373
- * Utilize the new core Ruby interceptors in gRPC 1.7
374
- * Support client interceptors
375
421
  * Change configuration to an injectable object to ensure thread safety on chained server/client interactions
376
422
  * Move all references to `Gruf.` configuration into injectable parameters
377
423
  * Redo server configuration to be fully injectable
378
- * Move client calls to their native method implementation
379
424
 
380
425
  ## Companies Using Gruf
381
426
 
data/bin/gruf CHANGED
@@ -25,15 +25,5 @@ end
25
25
  load 'config/environment.rb' if defined?(Rails)
26
26
  require 'gruf'
27
27
 
28
- begin
29
- server = Gruf::Server.new(Gruf.server_options)
30
- Gruf.services.each { |s| server.add_service(s) }
31
- server.start!
32
- rescue => e
33
- msg = "FATAL ERROR: #{e.message} #{e.backtrace.join("\n")}"
34
- if Gruf.logger
35
- Gruf.logger.fatal msg
36
- else
37
- Logger.new(STDOUT).fatal msg
38
- end
39
- end
28
+ cli = Gruf::Cli::Executor.new
29
+ cli.run
@@ -39,4 +39,5 @@ Gem::Specification.new do |spec|
39
39
  spec.add_runtime_dependency 'grpc', '~> 1.10'
40
40
  spec.add_runtime_dependency 'grpc-tools', '~> 1.10'
41
41
  spec.add_runtime_dependency 'activesupport'
42
+ spec.add_runtime_dependency 'slop', '~> 4.6'
42
43
  end
@@ -23,7 +23,9 @@ require_relative 'gruf/logging'
23
23
  require_relative 'gruf/loggable'
24
24
  require_relative 'gruf/configuration'
25
25
  require_relative 'gruf/errors/helpers'
26
+ require_relative 'gruf/cli/executor'
26
27
  require_relative 'gruf/controllers/base'
28
+ require_relative 'gruf/outbound/request_context'
27
29
  require_relative 'gruf/interceptors/registry'
28
30
  require_relative 'gruf/interceptors/base'
29
31
  require_relative 'gruf/timer'
@@ -0,0 +1,71 @@
1
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
7
+ #
8
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9
+ # Software.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ #
16
+ require 'slop'
17
+
18
+ module Gruf
19
+ module Cli
20
+ ##
21
+ # Handles execution of the gruf binstub, along with command-line arguments
22
+ #
23
+ class Executor
24
+ ##
25
+ # @param [Hash|ARGV]
26
+ #
27
+ def initialize(args = ARGV)
28
+ @args = args
29
+ setup!
30
+ end
31
+
32
+ ##
33
+ # Run the server
34
+ #
35
+ def run
36
+ server = Gruf::Server.new(Gruf.server_options)
37
+ Gruf.services.each { |s| server.add_service(s) }
38
+ server.start!
39
+ rescue StandardError => e
40
+ msg = "FATAL ERROR: #{e.message} #{e.backtrace.join("\n")}"
41
+ logger = Gruf.logger ? Gruf.logger : Logger.new(STDERR)
42
+ logger.fatal msg
43
+ end
44
+
45
+ private
46
+
47
+ ##
48
+ # Setup options for CLI execution and configure Gruf based on inputs
49
+ #
50
+ def setup!
51
+ opts = Slop.parse(@args) do |o|
52
+ o.null '-h', '--help', 'Display help message' do
53
+ puts o
54
+ exit(0)
55
+ end
56
+ o.string '--host', 'Specify the binding url for the gRPC service'
57
+ o.bool '--suppress-default-interceptors', 'Do not use the default interceptors'
58
+ o.bool '--backtrace-on-error', 'Push backtraces on exceptions to the error serializer'
59
+ o.null '-v', '--version', 'print gruf version' do
60
+ puts Gruf::VERSION
61
+ exit(0)
62
+ end
63
+ end
64
+
65
+ Gruf.server_binding_url = opts[:host] if opts[:host]
66
+ Gruf.use_default_interceptors = false if opts.suppress_default_interceptors?
67
+ Gruf.backtrace_on_error = true if opts.backtrace_on_error?
68
+ end
69
+ end
70
+ end
71
+ end
@@ -32,11 +32,11 @@ module Gruf
32
32
  ##
33
33
  # Initialize the controller within the given request context
34
34
  #
35
- # @param [Symbol] method_key
36
- # @param [GRPC::GenericService] service
37
- # @param [GRPC::RpcDesc] rpc_desc
38
- # @param [GRPC::ActiveCall] active_call
39
- # @param [Google::Protobuf::MessageExts] message
35
+ # @param [Symbol] method_key The gRPC method that this controller relates to
36
+ # @param [GRPC::GenericService] service The gRPC service stub for this controller
37
+ # @param [GRPC::RpcDesc] rpc_desc The RPC descriptor for this service method
38
+ # @param [GRPC::ActiveCall] active_call The gRPC ActiveCall object
39
+ # @param [Google::Protobuf::MessageExts] message The incoming protobuf request message
40
40
  #
41
41
  def initialize(method_key:, service:, rpc_desc:, active_call:, message:)
42
42
  @request = Request.new(
@@ -53,7 +53,7 @@ module Gruf
53
53
  ##
54
54
  # Bind the controller to the given service and add it to the service registry
55
55
  #
56
- # @param [GRPC::GenericService] service
56
+ # @param [GRPC::GenericService] service The name of the service to bind this controller to
57
57
  #
58
58
  def self.bind(service)
59
59
  Gruf.services << service.name.constantize
@@ -63,7 +63,8 @@ module Gruf
63
63
  ##
64
64
  # Call a method on this controller
65
65
  #
66
- # @param [Symbol] method_key
66
+ # @param [Symbol] method_key The name of the gRPC service method being called as a Symbol
67
+ # @param [block] &block The passed block for executing the method
67
68
  #
68
69
  def call(method_key, &block)
69
70
  Interceptors::Context.new(@interceptors).intercept! do
@@ -33,11 +33,16 @@ module Gruf
33
33
  delegate :metadata, to: :active_call
34
34
  delegate :messages, :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :type
35
35
 
36
+ ##
37
+ # Abstract representation of a gRPC request type
38
+ #
36
39
  class Type
37
40
  delegate :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :@rpc_desc
38
41
 
39
42
  ##
40
- # @param [GRPC::RpcDesc] rpc_desc
43
+ # Initialize a new request type object
44
+ #
45
+ # @param [GRPC::RpcDesc] rpc_desc The RPC descriptor for the request type
41
46
  #
42
47
  def initialize(rpc_desc)
43
48
  @rpc_desc = rpc_desc
@@ -45,6 +50,8 @@ module Gruf
45
50
  end
46
51
 
47
52
  ##
53
+ # Initialize an inbound controller request object
54
+ #
48
55
  # @param [Symbol] method_key The method symbol of the RPC method being executed
49
56
  # @param [Class] service The class of the service being executed against
50
57
  # @param [GRPC::RpcDesc] rpc_desc The RPC descriptor of the call
@@ -64,21 +71,21 @@ module Gruf
64
71
  # Returns the service name as a translated name separated by periods. Strips
65
72
  # the superfluous "Service" suffix from the name
66
73
  #
67
- # @return [String]
74
+ # @return [String] The mapped service key
68
75
  #
69
76
  def service_key
70
77
  @service.name.underscore.tr('/', '.').gsub('.service', '')
71
78
  end
72
79
 
73
80
  ##
74
- # @return [Class]
81
+ # @return [Class] The class of the response message
75
82
  #
76
83
  def response_class
77
84
  @rpc_desc.output
78
85
  end
79
86
 
80
87
  ##
81
- # @return [Class]
88
+ # @return [Class] The class of the request message
82
89
  #
83
90
  def request_class
84
91
  @rpc_desc.input
@@ -96,7 +103,7 @@ module Gruf
96
103
  ##
97
104
  # Return all messages for this request, properly handling different request types
98
105
  #
99
- # @return Enumerable<Object>
106
+ # @return Enumerable<Object> All messages for this request
100
107
  #
101
108
  def messages
102
109
  if client_streamer?
@@ -25,14 +25,18 @@ module Gruf
25
25
  class BoundDesc < SimpleDelegator; end
26
26
 
27
27
  ##
28
- # @param [GRPC::GenericService] service
28
+ # Initialize a service binder instance with the given service
29
+ #
30
+ # @param [GRPC::GenericService] service The gRPC service stub to bind
29
31
  #
30
32
  def initialize(service)
31
33
  @service = service
32
34
  end
33
35
 
34
36
  ##
35
- # @param [Gruf::Controllers::Base]
37
+ # Bind all methods on the service to the passed controller
38
+ #
39
+ # @param [Gruf::Controllers::Base] controller
36
40
  #
37
41
  def bind!(controller)
38
42
  rpc_methods.each { |name, desc| bind_method(controller, name, desc) }
@@ -41,6 +45,8 @@ module Gruf
41
45
  private
42
46
 
43
47
  ##
48
+ # Bind the grpc methods to the service, allowing for server interception and execution control
49
+ #
44
50
  # @param [Gruf::Controllers::Base] controller
45
51
  # @param [Symbol] method_name
46
52
  # @param [BoundDesc] desc
@@ -36,7 +36,7 @@ module Gruf
36
36
  ##
37
37
  # Return this object marshalled into a hash
38
38
  #
39
- # @return [Hash] The debug info represented as a has
39
+ # @return [Hash] The debug info represented as a hash
40
40
  #
41
41
  def to_h
42
42
  {
@@ -15,6 +15,9 @@
15
15
  #
16
16
  module Gruf
17
17
  module Errors
18
+ ##
19
+ # Helper module for standardizing error interaction
20
+ #
18
21
  module Helpers
19
22
  delegate :add_field_error, :set_debug_info, :has_field_errors?, to: :error
20
23
 
@@ -40,6 +40,7 @@ module Gruf
40
40
  end
41
41
  end
42
42
 
43
+ require_relative 'client_interceptor'
43
44
  require_relative 'server_interceptor'
44
45
  require_relative 'context'
45
46
  require_relative 'timer'
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
7
+ #
8
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9
+ # Software.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ #
16
+ module Gruf
17
+ module Interceptors
18
+ ##
19
+ # Intercepts outbound client requests to provide a unified interface and request context
20
+ #
21
+ class ClientInterceptor < GRPC::ClientInterceptor
22
+ include Gruf::Loggable
23
+
24
+ ##
25
+ # Handles interception of outbound calls. Implement this in your derivative interceptor implementation.
26
+ #
27
+ # @param [Gruf::Outbound::RequestContext] request_context The context of the outbound request
28
+ # @return [Object] This method must return the response from the yielded block
29
+ #
30
+ def call(request_context:)
31
+ logger.debug "Logging client interceptor for request: #{request_context.method}"
32
+ yield
33
+ end
34
+
35
+ ##
36
+ # Call the interceptor from the request_response call
37
+ #
38
+ # @param [Object] request The request being sent
39
+ # @param [GRPC::ActiveCall] call The GRPC ActiveCall object
40
+ # @param [Method] method The method being called
41
+ # @param [Hash] metadata A hash of outgoing metadata
42
+ # @return [Object] The response message
43
+ #
44
+ def request_response(request: nil, call: nil, method: nil, metadata: nil)
45
+ rc = Gruf::Outbound::RequestContext.new(type: :request_response, requests: [request], call: call, method: method, metadata: metadata)
46
+ call(request_context: rc) do
47
+ yield
48
+ end
49
+ end
50
+
51
+ ##
52
+ # Call the interceptor from the client_streamer call
53
+ #
54
+ # @param [Enumerable] requests An enumerable of requests being sent
55
+ # @param [GRPC::ActiveCall] call The GRPC ActiveCall object
56
+ # @param [Method] method The method being called
57
+ # @param [Hash] metadata A hash of outgoing metadata
58
+ # @return [Object] The response message
59
+ #
60
+ def client_streamer(requests: nil, call: nil, method: nil, metadata: nil)
61
+ rc = Gruf::Outbound::RequestContext.new(type: :client_streamer, requests: requests, call: call, method: method, metadata: metadata)
62
+ call(request_context: rc) do
63
+ yield
64
+ end
65
+ end
66
+
67
+ ##
68
+ # Call the interceptor from the server_streamer call
69
+ #
70
+ # @param [Object] request The request being sent
71
+ # @param [GRPC::ActiveCall] call The GRPC ActiveCall object
72
+ # @param [Method] method The method being called
73
+ # @param [Hash] metadata A hash of outgoing metadata
74
+ # @return [Object] The response message
75
+ #
76
+ def server_streamer(request: nil, call: nil, method: nil, metadata: nil)
77
+ rc = Gruf::Outbound::RequestContext.new(type: :server_streamer, requests: [request], call: call, method: method, metadata: metadata)
78
+ call(request_context: rc) do
79
+ yield
80
+ end
81
+ end
82
+
83
+ ##
84
+ # Call the interceptor from the bidi_streamer call
85
+ #
86
+ # @param [Enumerable] requests An enumerable of requests being sent
87
+ # @param [GRPC::ActiveCall] call The GRPC ActiveCall object
88
+ # @param [Method] method The method being called
89
+ # @param [Hash] metadata A hash of outgoing metadata
90
+ #
91
+ def bidi_streamer(requests: nil, call: nil, method: nil, metadata: nil)
92
+ rc = Gruf::Outbound::RequestContext.new(type: :bidi_streamer, requests: requests, call: call, method: method, metadata: metadata)
93
+ call(request_context: rc) do
94
+ yield
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -26,6 +26,11 @@ module Gruf
26
26
  attr_reader :message
27
27
  attr_reader :elapsed
28
28
 
29
+ ##
30
+ # @param [Object] message The protobuf message
31
+ # @param [Float] elapsed The elapsed time of the request
32
+ # @param [Boolean] successful If the request was successful
33
+ #
29
34
  def initialize(message, elapsed, successful)
30
35
  @message = message
31
36
  @elapsed = elapsed.to_f
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
7
+ #
8
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9
+ # Software.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ #
16
+ module Gruf
17
+ module Outbound
18
+ ##
19
+ # Encapsulates the context of an outbound client request
20
+ #
21
+ class RequestContext
22
+ # @var [Symbol]
23
+ attr_reader :type
24
+ # @var [Enumerable] requests
25
+ attr_reader :requests
26
+ # @var [GRPC::ActiveCall]
27
+ attr_reader :call
28
+ # @var [Method] method
29
+ attr_reader :method
30
+ # @var [Hash] metadata
31
+ attr_reader :metadata
32
+
33
+ ##
34
+ # Initialize the new request context
35
+ #
36
+ # @param [Symbol] type The type of request
37
+ # @param [Enumerable] requests An enumerable of requests being sent
38
+ # @param [GRPC::ActiveCall] call The GRPC ActiveCall object
39
+ # @param [Method] method The method being called
40
+ # @param [Hash] metadata A hash of outgoing metadata
41
+ #
42
+ def initialize(type:, requests:, call:, method:, metadata:)
43
+ @type = type
44
+ @requests = requests
45
+ @call = call
46
+ @method = method
47
+ @metadata = metadata
48
+ end
49
+
50
+ ##
51
+ # Return the name of the method being called, e.g. GetThing
52
+ #
53
+ # @return [String]
54
+ #
55
+ def method_name
56
+ @method.to_s.split('/').last
57
+ end
58
+
59
+ ##
60
+ # Return the proper routing key for the request
61
+ #
62
+ # @return [String]
63
+ #
64
+ def route_key
65
+ @method[1..-1].underscore.tr('/', '.')
66
+ end
67
+ end
68
+ end
69
+ end
@@ -43,6 +43,7 @@ module Gruf
43
43
  @stop_server_cv = ConditionVariable.new
44
44
  @stop_server_mu = Monitor.new
45
45
  @server_mu = Monitor.new
46
+ @hostname = options.fetch(:hostname, Gruf.server_binding_url)
46
47
  setup
47
48
  end
48
49
 
@@ -53,7 +54,7 @@ module Gruf
53
54
  @server_mu.synchronize do
54
55
  @server ||= begin
55
56
  server = GRPC::RpcServer.new(options)
56
- @port = server.add_http2_port(options.fetch(:hostname, Gruf.server_binding_url), ssl_credentials)
57
+ @port = server.add_http2_port(@hostname, ssl_credentials)
57
58
  @services.each { |s| server.handle(s) }
58
59
  server
59
60
  end
@@ -68,7 +69,7 @@ module Gruf
68
69
  update_proc_title(:starting)
69
70
 
70
71
  server_thread = Thread.new do
71
- logger.info { 'Booting gRPC Server...' }
72
+ logger.info { "Starting gruf server at #{@hostname}..." }
72
73
  server.run
73
74
  end
74
75
 
@@ -94,6 +95,8 @@ module Gruf
94
95
  # :nocov:
95
96
 
96
97
  ##
98
+ # Add a gRPC service stub to be served by gruf
99
+ #
97
100
  # @param [Class] klass
98
101
  # @raise [ServerAlreadyStartedError] if the server is already started
99
102
  #
@@ -115,6 +118,8 @@ module Gruf
115
118
  end
116
119
 
117
120
  ##
121
+ # Insert an interceptor before another in the currently registered order of execution
122
+ #
118
123
  # @param [Class] before_class The interceptor that you want to add the new interceptor before
119
124
  # @param [Class] interceptor_class The Interceptor to add to the registry
120
125
  # @param [Hash] options A hash of options for the interceptor
@@ -125,6 +130,8 @@ module Gruf
125
130
  end
126
131
 
127
132
  ##
133
+ # Insert an interceptor after another in the currently registered order of execution
134
+ #
128
135
  # @param [Class] after_class The interceptor that you want to add the new interceptor after
129
136
  # @param [Class] interceptor_class The Interceptor to add to the registry
130
137
  # @param [Hash] options A hash of options for the interceptor
@@ -146,6 +153,8 @@ module Gruf
146
153
  ##
147
154
  # Remove an interceptor from the server
148
155
  #
156
+ # @param [Class] klass
157
+ #
149
158
  def remove_interceptor(klass)
150
159
  raise ServerAlreadyStartedError if @started
151
160
  @interceptors.remove(klass)
@@ -14,5 +14,5 @@
14
14
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
15
  #
16
16
  module Gruf
17
- VERSION = '2.2.2'.freeze
17
+ VERSION = '2.3.0'.freeze
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gruf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shaun McCormick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-23 00:00:00.000000000 Z
11
+ date: 2018-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: slop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '4.6'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '4.6'
97
111
  description: gRPC Ruby Framework
98
112
  email:
99
113
  - splittingred@gmail.com
@@ -108,6 +122,7 @@ files:
108
122
  - bin/gruf
109
123
  - gruf.gemspec
110
124
  - lib/gruf.rb
125
+ - lib/gruf/cli/executor.rb
111
126
  - lib/gruf/client.rb
112
127
  - lib/gruf/configuration.rb
113
128
  - lib/gruf/controllers/base.rb
@@ -120,6 +135,7 @@ files:
120
135
  - lib/gruf/interceptors/active_record/connection_reset.rb
121
136
  - lib/gruf/interceptors/authentication/basic.rb
122
137
  - lib/gruf/interceptors/base.rb
138
+ - lib/gruf/interceptors/client_interceptor.rb
123
139
  - lib/gruf/interceptors/context.rb
124
140
  - lib/gruf/interceptors/instrumentation/output_metadata_timer.rb
125
141
  - lib/gruf/interceptors/instrumentation/request_logging/formatters/base.rb
@@ -132,6 +148,7 @@ files:
132
148
  - lib/gruf/interceptors/timer.rb
133
149
  - lib/gruf/loggable.rb
134
150
  - lib/gruf/logging.rb
151
+ - lib/gruf/outbound/request_context.rb
135
152
  - lib/gruf/response.rb
136
153
  - lib/gruf/serializers/errors/base.rb
137
154
  - lib/gruf/serializers/errors/json.rb