gruf 2.4.1 → 2.4.2
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 +4 -4
- data/CHANGELOG.md +25 -11
- data/README.md +9 -5
- data/lib/gruf/configuration.rb +1 -0
- data/lib/gruf/controllers/base.rb +2 -2
- data/lib/gruf/error.rb +29 -7
- data/lib/gruf/errors/debug_info.rb +6 -1
- data/lib/gruf/server.rb +0 -2
- data/lib/gruf/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bef9466a137b8d52bc76a4d24c65fef26b0701cff21eefb2ae9811e020dd619c
|
4
|
+
data.tar.gz: f3209bfefd0e3a7fe7ee03b6bcc7a417974593b924966521346d095d87de6d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 906fa455028407ea0ac54dceeb89c54b032ddf9e1090e85d14dabf8496aad91b22d19056fdf8e84d9836399518198ed7afffa50c1cc69ac9d8a4e5a43e53f40b
|
7
|
+
data.tar.gz: c3ec65443321ff6ac00b839bf3b6a9fed748e5f7ab2ec73ffd4476d1b4b7590ccd2d865ac4f5c6703a59c5ae89746b2964f58ee43e56c62a3df62e8bddae9271
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,20 @@ Changelog for the gruf gem. This includes internal history before the gem was ma
|
|
2
2
|
|
3
3
|
### Pending release
|
4
4
|
|
5
|
+
### 2.4.2
|
6
|
+
|
7
|
+
- Added error handling for GRPC::Core::CallError, a low-level error in the grpc library that does not inherit
|
8
|
+
from StandardError. [#59]
|
9
|
+
- Removed `Thread.abort\_on\_exception = true`. Exceptions should be handled by gruf or the application,
|
10
|
+
and should not cause the server process to crash. [#59]
|
11
|
+
- Added guard for size of trailing metadata attached to grpc call. The default max for http2 trailing metadata
|
12
|
+
in the gRPC C library is 8kb. If we go over that limit (either through custom metadata attached to the
|
13
|
+
error by the application, or via the error payload encoded by the error serializer), the gRPC library
|
14
|
+
will throw RESOURCE\_EXHAUSTED. Gruf now detects this case, and attempts to prevent it by logging the
|
15
|
+
original error and substituting it with an internal error indicating that the metadata was too large. [#60]
|
16
|
+
- Truncate stack trace in error payload to help avoid overflowing the trailing metadata. Added backtrace\_limit
|
17
|
+
configuration parameter, which defaults to 10.[#60]
|
18
|
+
|
5
19
|
### 2.4.1
|
6
20
|
|
7
21
|
- Safer configuration of GRPC::RpcServer. From now on, use `Gruf.rpc_server_options` for the params
|
@@ -12,8 +26,8 @@ Changelog for the gruf gem. This includes internal history before the gem was ma
|
|
12
26
|
|
13
27
|
### 2.4.0
|
14
28
|
|
15
|
-
- Added a hash of error log levels to RequestLogging interceptor, mapping error code to level of logging to use. To
|
16
|
-
override the level of logging per error response, provide a map of codes to log level in options, key :log_levels.
|
29
|
+
- Added a hash of error log levels to RequestLogging interceptor, mapping error code to level of logging to use. To
|
30
|
+
override the level of logging per error response, provide a map of codes to log level in options, key :log_levels.
|
17
31
|
The default is :error log level.
|
18
32
|
|
19
33
|
### 2.3.0
|
@@ -28,7 +42,7 @@ The default is :error log level.
|
|
28
42
|
|
29
43
|
### 2.2.1
|
30
44
|
|
31
|
-
- Now changes proc title once server is ready to process incoming requests [#44]
|
45
|
+
- Now changes proc title once server is ready to process incoming requests [#44]
|
32
46
|
- Gruf now requires gRPC 1.10.x+ due to various fixes and improvements in the gRPC core libraries
|
33
47
|
|
34
48
|
### 2.2.0
|
@@ -37,13 +51,13 @@ The default is :error log level.
|
|
37
51
|
|
38
52
|
### 2.1.1
|
39
53
|
|
40
|
-
- Add ability to pass in client stub options into Gruf::Client
|
54
|
+
- Add ability to pass in client stub options into Gruf::Client
|
41
55
|
|
42
56
|
### 2.1.0
|
43
57
|
|
44
58
|
- Add ability to list, clear, insert before, insert after, and remove to a server's interceptor
|
45
59
|
registry
|
46
|
-
- Ensure interceptors and services cannot be adjusted on the server after it starts to
|
60
|
+
- Ensure interceptors and services cannot be adjusted on the server after it starts to
|
47
61
|
prevent threading issues
|
48
62
|
- [#36], [#37] Adds `response_class`, `request_class`, and `service` accessors to controller request
|
49
63
|
|
@@ -106,22 +120,22 @@ Gruf 2.0 is a major shift from Gruf 1.0. See [UPGRADING.md](UPGRADING.md) for de
|
|
106
120
|
- Instrumentation hooks now execute similarly to outer_around hooks; they can
|
107
121
|
now instrument failures
|
108
122
|
- Instrumentation hooks now pass a `RequestContext` object that contains information
|
109
|
-
about the incoming request, instead of relying on instance variables
|
123
|
+
about the incoming request, instead of relying on instance variables
|
110
124
|
- StatsD hook now sends success/failure metrics for endpoints
|
111
125
|
- Add ability to turn off sending exception message on uncaught exception.
|
112
126
|
- Add configuration to set the error message when an uncaught exception is
|
113
127
|
handled by gruf.
|
114
|
-
- Add a request logging hook for Rails-style request logging, with optional
|
115
|
-
parameter logging, blacklists, and formatter support
|
128
|
+
- Add a request logging hook for Rails-style request logging, with optional
|
129
|
+
parameter logging, blacklists, and formatter support
|
116
130
|
- Optimizations around Symbol casting within service calls
|
117
131
|
|
118
132
|
### 1.1.0
|
119
133
|
|
120
|
-
- Add the ability for call options to the client, which enables deadline setting
|
134
|
+
- Add the ability for call options to the client, which enables deadline setting
|
121
135
|
|
122
136
|
### 1.0.0
|
123
137
|
|
124
|
-
- Bump gRPC to 1.4
|
138
|
+
- Bump gRPC to 1.4
|
125
139
|
|
126
140
|
### 0.14.2
|
127
141
|
|
@@ -150,7 +164,7 @@ Gruf 2.0 is a major shift from Gruf 1.0. See [UPGRADING.md](UPGRADING.md) for de
|
|
150
164
|
### 0.12.0
|
151
165
|
|
152
166
|
- Add ability to run multiple around hooks
|
153
|
-
- Fix bug with error handling that caused error messages to repeat across streams
|
167
|
+
- Fix bug with error handling that caused error messages to repeat across streams
|
154
168
|
|
155
169
|
### 0.11.5
|
156
170
|
|
data/README.md
CHANGED
@@ -87,9 +87,9 @@ end
|
|
87
87
|
|
88
88
|
::Gruf::Client.new(
|
89
89
|
service: ::Demo::ThingService,
|
90
|
-
client_options:
|
90
|
+
client_options: {
|
91
91
|
interceptors: [MyInterceptor.new]
|
92
|
-
|
92
|
+
})
|
93
93
|
```
|
94
94
|
|
95
95
|
The `interceptors` option in `client_options` can accept either a `GRPC::ClientInterceptor` class or a
|
@@ -239,9 +239,11 @@ For the client, you'll need to point to the public certificate:
|
|
239
239
|
```ruby
|
240
240
|
::Gruf::Client.new(
|
241
241
|
service: Demo::ThingService,
|
242
|
-
|
243
|
-
|
244
|
-
|
242
|
+
options: {
|
243
|
+
ssl_certificate: 'x509 public certificate here',
|
244
|
+
# OR
|
245
|
+
ssl_certificate_file: '/path/to/my.crt'
|
246
|
+
}
|
245
247
|
)
|
246
248
|
```
|
247
249
|
|
@@ -485,6 +487,8 @@ gruf that you can use today:
|
|
485
487
|
|
486
488
|
* [gruf-zipkin](https://github.com/bigcommerce/gruf-zipkin) - Provides a [Zipkin](https://zipkin.io)
|
487
489
|
integration
|
490
|
+
* [gruf-lightstep](https://github.com/bigcommerce/gruf-lightstep) - Provides a seamless
|
491
|
+
[LightStep](https://lightstep.com) integration
|
488
492
|
* [gruf-circuit-breaker](https://github.com/bigcommerce/gruf-circuit-breaker) - Circuit breaker
|
489
493
|
support for services
|
490
494
|
* [gruf-profiler](https://github.com/bigcommerce/gruf-profiler) - Profiles and provides memory usage
|
data/lib/gruf/configuration.rb
CHANGED
@@ -36,6 +36,7 @@ module Gruf
|
|
36
36
|
append_server_errors_to_trailing_metadata: true,
|
37
37
|
use_default_interceptors: true,
|
38
38
|
backtrace_on_error: false,
|
39
|
+
backtrace_limit: 10,
|
39
40
|
use_exception_message: true,
|
40
41
|
internal_error_message: 'Internal Server Error',
|
41
42
|
event_listener_proc: nil,
|
@@ -71,8 +71,8 @@ module Gruf
|
|
71
71
|
send(method_key, &block)
|
72
72
|
end
|
73
73
|
rescue GRPC::BadStatus
|
74
|
-
raise # passthrough
|
75
|
-
rescue StandardError => e
|
74
|
+
raise # passthrough, to be caught by Gruf::Interceptors::Timer
|
75
|
+
rescue GRPC::Core::CallError, StandardError => e # CallError is not a StandardError
|
76
76
|
set_debug_info(e.message, e.backtrace) if Gruf.backtrace_on_error
|
77
77
|
error_message = Gruf.use_exception_message ? e.message : Gruf.internal_error_message
|
78
78
|
fail!(:internal, :unknown, error_message)
|
data/lib/gruf/error.rb
CHANGED
@@ -50,6 +50,13 @@ module Gruf
|
|
50
50
|
data_loss: GRPC::DataLoss
|
51
51
|
}.freeze
|
52
52
|
|
53
|
+
# Default limit on trailing metadata is 8KB. We need to be careful
|
54
|
+
# not to overflow this limit, or the response message will never
|
55
|
+
# be sent. Instead, resource_exhausted will be thrown.
|
56
|
+
MAX_METADATA_SIZE = 7.5 * 1_024
|
57
|
+
METADATA_SIZE_EXCEEDED_CODE = 'metadata_size_exceeded'.freeze
|
58
|
+
METADATA_SIZE_EXCEEDED_MSG = 'Metadata too long, risks exceeding http2 trailing metadata limit.'.freeze
|
59
|
+
|
53
60
|
# @return [Symbol] The given internal gRPC code for the error
|
54
61
|
attr_accessor :code
|
55
62
|
# @return [Symbol] An arbitrary application code that can be used for logical processing of the error by the client
|
@@ -58,8 +65,8 @@ module Gruf
|
|
58
65
|
attr_accessor :message
|
59
66
|
# @return [Array] An array of field errors that can be returned by the server
|
60
67
|
attr_accessor :field_errors
|
61
|
-
# @return [
|
62
|
-
# debug an given error response. This is sent by the server over the trailing metadata.
|
68
|
+
# @return [Errors::DebugInfo] A object containing debugging information, such as a stack trace and exception name,
|
69
|
+
# that can be used to debug an given error response. This is sent by the server over the trailing metadata.
|
63
70
|
attr_accessor :debug_info
|
64
71
|
# @return [GRPC::BadStatus] The gRPC BadStatus error object that was generated
|
65
72
|
attr_writer :grpc_error
|
@@ -72,10 +79,11 @@ module Gruf
|
|
72
79
|
# @param [Hash] args (Optional) An optional hash of arguments that will set fields on the error object
|
73
80
|
#
|
74
81
|
def initialize(args = {})
|
82
|
+
@field_errors = []
|
83
|
+
@metadata = {}
|
75
84
|
args.each do |k, v|
|
76
85
|
send("#{k}=", v) if respond_to?(k)
|
77
86
|
end
|
78
|
-
@field_errors = []
|
79
87
|
end
|
80
88
|
|
81
89
|
##
|
@@ -130,16 +138,30 @@ module Gruf
|
|
130
138
|
end
|
131
139
|
|
132
140
|
##
|
133
|
-
#
|
141
|
+
# Update the trailing metadata on the given gRPC call, including the error payload if configured
|
142
|
+
# to do so.
|
134
143
|
#
|
135
144
|
# @param [GRPC::ActiveCall] active_call The marshalled gRPC call
|
136
|
-
# @return [Error] Return the error itself
|
145
|
+
# @return [Error] Return the error itself after updating metadata on the given gRPC call.
|
146
|
+
# In the case of a metadata overflow error, we replace the current error with
|
147
|
+
# a new one that won't cause a low-level http2 error.
|
137
148
|
#
|
138
149
|
def attach_to_call(active_call)
|
139
150
|
metadata[Gruf.error_metadata_key.to_sym] = serialize if Gruf.append_server_errors_to_trailing_metadata
|
140
|
-
if
|
141
|
-
|
151
|
+
return self if metadata.empty? || !active_call || !active_call.respond_to?(:output_metadata)
|
152
|
+
|
153
|
+
# Check if we've overflown the maximum size of output metadata. If so,
|
154
|
+
# log a warning and replace the metadata with something smaller to avoid
|
155
|
+
# resource exhausted errors.
|
156
|
+
if metadata.inspect.size > MAX_METADATA_SIZE
|
157
|
+
code = METADATA_SIZE_EXCEEDED_CODE
|
158
|
+
msg = METADATA_SIZE_EXCEEDED_MSG
|
159
|
+
logger.warn "#{code}: #{msg} Original error: #{to_h.inspect}"
|
160
|
+
err = Gruf::Error.new(code: :internal, app_code: code, message: msg)
|
161
|
+
return err.attach_to_call(active_call)
|
142
162
|
end
|
163
|
+
|
164
|
+
active_call.output_metadata.update(metadata)
|
143
165
|
self
|
144
166
|
end
|
145
167
|
|
@@ -30,7 +30,12 @@ module Gruf
|
|
30
30
|
#
|
31
31
|
def initialize(detail, stack_trace = [])
|
32
32
|
@detail = detail
|
33
|
-
@stack_trace = stack_trace.is_a?(String) ? stack_trace.split("\n") : stack_trace
|
33
|
+
@stack_trace = (stack_trace.is_a?(String) ? stack_trace.split("\n") : stack_trace)
|
34
|
+
|
35
|
+
# Limit the size of the stack trace to reduce risk of overflowing metadata
|
36
|
+
stack_trace_limit = Gruf.backtrace_limit.to_i
|
37
|
+
stack_trace_limit = 10 if stack_trace_limit < 0
|
38
|
+
@stack_trace = @stack_trace[0..stack_trace_limit] if stack_trace_limit > 0
|
34
39
|
end
|
35
40
|
|
36
41
|
##
|
data/lib/gruf/server.rb
CHANGED
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.
|
4
|
+
version: 2.4.2
|
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-
|
11
|
+
date: 2018-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|