gruf 1.1.0 → 1.2.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -19
  3. data/README.md +71 -21
  4. data/lib/gruf.rb +3 -0
  5. data/lib/gruf/authentication.rb +9 -1
  6. data/lib/gruf/authentication/base.rb +16 -8
  7. data/lib/gruf/authentication/basic.rb +6 -6
  8. data/lib/gruf/authentication/none.rb +2 -2
  9. data/lib/gruf/authentication/strategies.rb +20 -7
  10. data/lib/gruf/client.rb +73 -11
  11. data/lib/gruf/configuration.rb +9 -6
  12. data/lib/gruf/error.rb +49 -15
  13. data/lib/gruf/errors/debug_info.rb +10 -5
  14. data/lib/gruf/errors/field.rb +12 -5
  15. data/lib/gruf/hooks/active_record/connection_reset.rb +15 -1
  16. data/lib/gruf/hooks/base.rb +26 -4
  17. data/lib/gruf/hooks/registry.rb +15 -9
  18. data/lib/gruf/instrumentation/base.rb +66 -11
  19. data/lib/gruf/instrumentation/output_metadata_timer.rb +6 -3
  20. data/lib/gruf/instrumentation/registry.rb +22 -13
  21. data/lib/gruf/instrumentation/request_context.rb +66 -0
  22. data/lib/gruf/instrumentation/request_logging/formatters/base.rb +38 -0
  23. data/lib/gruf/instrumentation/request_logging/formatters/logstash.rb +40 -0
  24. data/lib/gruf/instrumentation/request_logging/formatters/plain.rb +45 -0
  25. data/lib/gruf/instrumentation/request_logging/hook.rb +145 -0
  26. data/lib/gruf/instrumentation/statsd.rb +19 -13
  27. data/lib/gruf/loggable.rb +4 -1
  28. data/lib/gruf/logging.rb +19 -0
  29. data/lib/gruf/response.rb +19 -4
  30. data/lib/gruf/serializers/errors/base.rb +10 -3
  31. data/lib/gruf/serializers/errors/json.rb +5 -2
  32. data/lib/gruf/server.rb +10 -2
  33. data/lib/gruf/service.rb +32 -22
  34. data/lib/gruf/timer.rb +26 -5
  35. data/lib/gruf/version.rb +1 -1
  36. metadata +7 -2
@@ -22,8 +22,14 @@ module Gruf
22
22
  class Server
23
23
  include Gruf::Loggable
24
24
 
25
+ # @return [Array<Class>] The services this server is handling
25
26
  attr_accessor :services
26
27
 
28
+ ##
29
+ # Initialize the server and load and setup the services
30
+ #
31
+ # @param [Array<Class>] services The services that this server should handle
32
+ #
27
33
  def initialize(services: [])
28
34
  setup!
29
35
  load_services(services)
@@ -50,8 +56,8 @@ module Gruf
50
56
  ##
51
57
  # Return all loaded gRPC services
52
58
  #
53
- # @param [Array<Class>] svcs
54
- # @return [Array<Class>]
59
+ # @param [Array<Class>] svcs An array of service classes that will be handled by this server
60
+ # @return [Array<Class>] The given services that were added
55
61
  #
56
62
  def load_services(svcs)
57
63
  unless @services
@@ -74,6 +80,8 @@ module Gruf
74
80
  # :nocov:
75
81
 
76
82
  ##
83
+ # Load the SSL/TLS credentials for this server
84
+ #
77
85
  # @return [GRPC::Core::ServerCredentials|Symbol]
78
86
  #
79
87
  # :nocov:
@@ -16,7 +16,10 @@
16
16
  #
17
17
  module Gruf
18
18
  ##
19
- # Module for gRPC endpoints
19
+ # Module for gRPC endpoints. Include this in any gRPC service you wish Gruf to serve. It will automatically mount
20
+ # it to the given gruf server and can be run via the command:
21
+ #
22
+ # bundle exec gruf
20
23
  #
21
24
  module Service
22
25
  extend ActiveSupport::Concern
@@ -37,7 +40,7 @@ module Gruf
37
40
  without = :"#{method_name}_without_intercept"
38
41
  @__last_methods_added = [method_name, with, without]
39
42
  define_method with do |*args, &block|
40
- call_chain(without, args[0], args[1], &block)
43
+ call_chain(method_name, args[0], args[1], &block)
41
44
  end
42
45
  alias_method without, method_name
43
46
  alias_method method_name, with
@@ -122,6 +125,12 @@ module Gruf
122
125
  #
123
126
  def outer_around_call(call_signature, req, call, &block)
124
127
  outer_around_hooks = []
128
+
129
+ # run instrumentation hooks as outer_around calls
130
+ Gruf::Instrumentation::Registry.each do |_name, h|
131
+ outer_around_hooks << h.new(self, Gruf.instrumentation_options)
132
+ end
133
+
125
134
  Gruf::Hooks::Registry.each do |_name, h|
126
135
  outer_around_hooks << h.new(self, Gruf.hook_options) if h.instance_methods.include?(:outer_around)
127
136
  end
@@ -187,7 +196,6 @@ module Gruf
187
196
  # @param [Symbol] app_code The application-specific code for the error
188
197
  # @param [String] message (Optional) A detail message about the error
189
198
  # @param [Hash] metadata (Optional) Any metadata to inject into the trailing metadata for the response
190
- # @return [RPC::Error]
191
199
  #
192
200
  def fail!(_req, call, error_code, app_code = nil, message = '', metadata = {})
193
201
  error.code = error_code.to_sym
@@ -202,41 +210,43 @@ module Gruf
202
210
  ##
203
211
  # Encapsulate the call chain to provide before/around/after hooks
204
212
  #
205
- # @param [Symbol] original_call_sig The original call signature for the service
213
+ # @param [String] original_call_sig The original call signature for the service
206
214
  # @param [Object] req The request object
207
215
  # @param [GRPC::ActiveCall] call The ActiveCall object being executed
208
216
  # @return [Object] The response object
209
217
  #
210
218
  def call_chain(original_call_sig, req, call, &block)
211
219
  outer_around_call(original_call_sig, req, call) do
212
- before_call(original_call_sig, req, call)
213
- timed = Timer.time do
214
- around_call(original_call_sig, req, call) do
215
- send(original_call_sig, req, call, &block) # send the actual request to gRPC
216
- end
217
- end
218
- after_call(timed.success?, timed.result, original_call_sig, req, call)
220
+ begin
221
+ before_call(original_call_sig, req, call)
219
222
 
220
- Gruf::Instrumentation::Registry.each do |_name, h|
221
- h.new(self, req, timed.result, timed.time, original_call_sig, call, Gruf.instrumentation_options).call
223
+ result = around_call(original_call_sig, req, call) do
224
+ send("#{original_call_sig}_without_intercept", req, call, &block) # send the actual request to gRPC
225
+ end
226
+ rescue GRPC::BadStatus => e
227
+ result = e
222
228
  end
229
+ success = !result.is_a?(GRPC::BadStatus)
230
+ after_call(success, result, original_call_sig, req, call)
223
231
 
224
- raise timed.result unless timed.success?
232
+ raise result unless success
225
233
 
226
- timed.result
234
+ result
227
235
  end
236
+ rescue GRPC::BadStatus
237
+ raise
228
238
  rescue => e
229
- raise e if e.is_a?(GRPC::BadStatus)
230
239
  set_debug_info(e.message, e.backtrace) if Gruf.backtrace_on_error
231
- fail!(req, call, :internal, :unknown, e.message)
240
+ error_message = Gruf.use_exception_message ? e.message : Gruf.internal_error_message
241
+ fail!(req, call, :internal, :unknown, error_message)
232
242
  end
233
243
 
234
244
  ##
235
245
  # Add a field error to this endpoint
236
246
  #
237
- # @param [Symbol] field_name
238
- # @param [Symbol] error_code
239
- # @param [String] message
247
+ # @param [Symbol] field_name The name of the field
248
+ # @param [Symbol] error_code The application error code for the field
249
+ # @param [String] message A given error message for the field
240
250
  #
241
251
  def add_field_error(field_name, error_code, message = '')
242
252
  error.add_field_error(field_name, error_code, message)
@@ -245,7 +255,7 @@ module Gruf
245
255
  ##
246
256
  # Return true if there are any present field errors
247
257
  #
248
- # @return [Boolean]
258
+ # @return [Boolean] True if the service has any field errors
249
259
  #
250
260
  def has_field_errors?
251
261
  error.field_errors.any?
@@ -262,7 +272,7 @@ module Gruf
262
272
  end
263
273
 
264
274
  ##
265
- # @return [Gruf::Error]
275
+ # @return [Gruf::Error] The generated gruf error object
266
276
  #
267
277
  def error
268
278
  @error ||= Gruf::Error.new
@@ -15,15 +15,30 @@
15
15
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
16
  #
17
17
  module Gruf
18
+ ##
19
+ # Times a given block and returns the result and the elapsed time as a Float
20
+ #
21
+ # result = Timer.time { do_my_thing }
22
+ #
18
23
  class Timer
19
-
24
+ ##
25
+ # Represents a timer result that contains both the elapsed time and the result of the block
26
+ #
27
+ # result = Timer.time { do_my_thing }
28
+ # result.time # => 1.10123
29
+ # result.result # => 'my_thing_is_done'
30
+ #
20
31
  class Result
32
+ # @return [Object] result The result of the block that was called
21
33
  attr_reader :result
34
+ # @return [Float] time The time, in ms, of the block execution
22
35
  attr_reader :time
23
36
 
24
37
  ##
25
- # @param [Object] result
26
- # @param [Float] time
38
+ # Initialize the result object
39
+ #
40
+ # @param [Object] result The result of the block that was called
41
+ # @param [Float] time The time, in ms, of the block execution
27
42
  #
28
43
  def initialize(result, time)
29
44
  @result = result
@@ -31,7 +46,9 @@ module Gruf
31
46
  end
32
47
 
33
48
  ##
34
- # @return [Boolean]
49
+ # Was this result a successful result?
50
+ #
51
+ # @return [Boolean] Whether or not this result was a success
35
52
  #
36
53
  def success?
37
54
  !result.is_a?(GRPC::BadStatus)
@@ -39,7 +56,11 @@ module Gruf
39
56
  end
40
57
 
41
58
  ##
42
- # @return [Timer::Result]
59
+ # Times a given block by recording start and end times
60
+ #
61
+ # result = Timer.time { do_my_thing }
62
+ #
63
+ # @return [Timer::Result] Returns the timed result of the block
43
64
  #
44
65
  def self.time
45
66
  start_time = Time.now
@@ -15,5 +15,5 @@
15
15
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
16
  #
17
17
  module Gruf
18
- VERSION = '1.1.0'.freeze
18
+ VERSION = '1.2.0'.freeze
19
19
  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: 1.1.0
4
+ version: 1.2.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: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -124,6 +124,11 @@ files:
124
124
  - lib/gruf/instrumentation/base.rb
125
125
  - lib/gruf/instrumentation/output_metadata_timer.rb
126
126
  - lib/gruf/instrumentation/registry.rb
127
+ - lib/gruf/instrumentation/request_context.rb
128
+ - lib/gruf/instrumentation/request_logging/formatters/base.rb
129
+ - lib/gruf/instrumentation/request_logging/formatters/logstash.rb
130
+ - lib/gruf/instrumentation/request_logging/formatters/plain.rb
131
+ - lib/gruf/instrumentation/request_logging/hook.rb
127
132
  - lib/gruf/instrumentation/statsd.rb
128
133
  - lib/gruf/loggable.rb
129
134
  - lib/gruf/logging.rb