gruf 2.2.2 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +48 -3
- data/bin/gruf +2 -12
- data/gruf.gemspec +1 -0
- data/lib/gruf.rb +2 -0
- data/lib/gruf/cli/executor.rb +71 -0
- data/lib/gruf/controllers/base.rb +8 -7
- data/lib/gruf/controllers/request.rb +12 -5
- data/lib/gruf/controllers/service_binder.rb +8 -2
- data/lib/gruf/errors/debug_info.rb +1 -1
- data/lib/gruf/errors/helpers.rb +3 -0
- data/lib/gruf/interceptors/base.rb +1 -0
- data/lib/gruf/interceptors/client_interceptor.rb +99 -0
- data/lib/gruf/interceptors/timer.rb +5 -0
- data/lib/gruf/outbound/request_context.rb +69 -0
- data/lib/gruf/server.rb +11 -2
- data/lib/gruf/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d13a8ed53bfc2a83d33c7ca8eed57d302019d9b7
|
4
|
+
data.tar.gz: c665d27586c8c446071275b1490c6814391e7f49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18b6a5bb4cc864ec8f9dd66428fd08843d71b27a5c61706f4d352e2554644b9e9062e37c8e165917c021cc1970560099920e8f7f3be0149f60b18fa35e86c02c
|
7
|
+
data.tar.gz: 6432ce2af8567422c3ee0dce084bac1f6100536421f4f93cfee554dd78384f989ac163247d81a52c3043123d06a4e841337198bb9e6a4cf2ce4dbdf36410cce2
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
-
|
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
|
-
|
29
|
-
|
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
|
data/gruf.gemspec
CHANGED
data/lib/gruf.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
data/lib/gruf/errors/helpers.rb
CHANGED
@@ -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
|
data/lib/gruf/server.rb
CHANGED
@@ -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(
|
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 {
|
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)
|
data/lib/gruf/version.rb
CHANGED
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.
|
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-
|
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
|