gruf 2.10.0 → 2.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/README.md +3 -3
- data/gruf.gemspec +5 -4
- data/lib/gruf/client/error.rb +2 -1
- data/lib/gruf/client.rb +7 -4
- data/lib/gruf/configuration.rb +98 -16
- data/lib/gruf/controllers/base.rb +6 -3
- data/lib/gruf/controllers/request.rb +12 -6
- data/lib/gruf/error.rb +16 -8
- data/lib/gruf/errors/debug_info.rb +4 -2
- data/lib/gruf/errors/field.rb +6 -3
- data/lib/gruf/interceptors/base.rb +6 -3
- data/lib/gruf/interceptors/context.rb +1 -1
- data/lib/gruf/interceptors/timer.rb +7 -3
- data/lib/gruf/outbound/request_context.rb +12 -7
- data/lib/gruf/response.rb +12 -6
- data/lib/gruf/serializers/errors/base.rb +2 -1
- data/lib/gruf/server.rb +29 -62
- data/lib/gruf/synchronized_client.rb +2 -0
- data/lib/gruf/timer.rb +6 -2
- data/lib/gruf/version.rb +1 -1
- data/lib/gruf.rb +1 -1
- metadata +11 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fdf24359533f0c174160c022698b4c3dff0358700a340f470abf68149619380
|
4
|
+
data.tar.gz: f5a07f92989697f5ca2625f21ab150dad8b0e9c848ace26833e11541bf83f2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1108582d41b071f520d393e9c4946fe90fe88c93cc26dbbb7c6980b580c586d27ddb69fee0b5ff7a89e2accd4aabd25f39635f0b04833a41eb369ce0b98bf6c0
|
7
|
+
data.tar.gz: 8082bb3b4f30ed4d45d7928fc7c34aaa2b13204d3adca682d9fab51641a72dac3692227edfe789062b2ef1b3e0b78b8cdb495e97c9cfe952bf59a9ee0370f408
|
data/CHANGELOG.md
CHANGED
@@ -2,11 +2,44 @@ Changelog for the gruf gem. This includes internal history before the gem was ma
|
|
2
2
|
|
3
3
|
### Pending release
|
4
4
|
|
5
|
+
### 2.13.1
|
6
|
+
|
7
|
+
- Fix issue with race condition in server starts where servers may fail to bind connections and never reach
|
8
|
+
serving state (fixes #147)
|
9
|
+
|
10
|
+
### 2.13.0
|
11
|
+
|
12
|
+
- Remove server mutex handling in deference to core grpc signal handling
|
13
|
+
- Relax grpc pin as upstream regression is fixed
|
14
|
+
|
15
|
+
### 2.12.0
|
16
|
+
|
17
|
+
- Fixed interceptor order to be FIFO as documented, instead of FILO (fixes #139)
|
18
|
+
|
19
|
+
### 2.11.0
|
20
|
+
|
21
|
+
- Restrict grpc gem to <= 1.41.0 due to regressions in grpc 1.42.x
|
22
|
+
- Fallback to stdout logger at INFO if no logger is setup
|
23
|
+
- Better handling of namespace collisions with Rails
|
24
|
+
- Add `GRPC_SERVER_HOST` and `GRPC_SERVER_PORT` for ENV configuration of the server host+port
|
25
|
+
- Add `GRPC_BACKTRACE_ON_ERROR` as available ENV configuration
|
26
|
+
- Add default ENV-based configuration of the GRPC server pool
|
27
|
+
- `GRPC_SERVER_POOL_SIZE` - sets the size of the GRPC server pool
|
28
|
+
- `GRPC_SERVER_POOL_KEEP_ALIVE` - keep alive time for threads spawned by the server pool
|
29
|
+
- `GRPC_SERVER_POLL_PERIOD` - period in seconds to poll for workers in the gRPC server pool
|
30
|
+
- Improve Yardoc support across the library
|
31
|
+
- Added attribute-based documentation for Gruf configuration options
|
32
|
+
- Add mfa required for gemspec metadata
|
33
|
+
|
5
34
|
### 2.10.0
|
6
35
|
|
7
36
|
- Drop support for Ruby 2.4/2.5 to align with Ruby EOL schedule, supporting 2.6+ only
|
8
37
|
- Allow for float/TimeSpec timeout values on clients
|
9
38
|
|
39
|
+
### 2.9.1
|
40
|
+
|
41
|
+
- Allow for float/TimeSpec timeout values on clients (backport from 2.10.0)
|
42
|
+
|
10
43
|
### 2.9.0
|
11
44
|
|
12
45
|
- Change to racially neutral terminology across library
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# gruf - gRPC Ruby Framework
|
2
2
|
|
3
|
-
[](https://circleci.com/gh/bigcommerce/gruf/tree/main) [](https://badge.fury.io/rb/gruf) [](https://inch-ci.org/github/bigcommerce/gruf?branch=main)
|
3
|
+
[](https://circleci.com/gh/bigcommerce/gruf/tree/main) [](https://badge.fury.io/rb/gruf) [](https://inch-ci.org/github/bigcommerce/gruf?branch=main) [](https://codeclimate.com/github/bigcommerce/gruf/maintainability) [](https://codeclimate.com/github/bigcommerce/gruf/test_coverage)
|
4
4
|
|
5
|
-
gruf is a Ruby framework that wraps the [gRPC Ruby library](https://github.com/grpc/grpc/tree/
|
5
|
+
gruf is a Ruby framework that wraps the [gRPC Ruby library](https://github.com/grpc/grpc/tree/master/src/ruby) to
|
6
6
|
provide a more streamlined integration into Ruby and Ruby on Rails applications.
|
7
7
|
|
8
8
|
It provides an abstracted server and client for gRPC services, along with other tools to help get gRPC services in Ruby
|
@@ -17,7 +17,7 @@ up fast and efficiently at scale. Some of its features include:
|
|
17
17
|
still preserving gRPC BadStatus codes
|
18
18
|
* Server and client execution timings in responses
|
19
19
|
|
20
|
-
gruf currently has active support for gRPC 1.10.x+. gruf is compatible and tested with Ruby 2.2-
|
20
|
+
gruf currently has active support for gRPC 1.10.x+. gruf is compatible and tested with Ruby 2.2-3.0.
|
21
21
|
gruf is also not [Rails](https://github.com/rails/rails)-specific, and can be used in any Ruby framework
|
22
22
|
(such as [Grape](https://github.com/ruby-grape/grape) or [dry-rb](https://dry-rb.org/), for instance).
|
23
23
|
|
data/gruf.gemspec
CHANGED
@@ -35,7 +35,8 @@ Gem::Specification.new do |spec|
|
|
35
35
|
|
36
36
|
spec.required_ruby_version = '>= 2.6', '< 3.1'
|
37
37
|
|
38
|
-
spec.
|
38
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
39
|
+
|
39
40
|
spec.add_development_dependency 'bundler-audit', '>= 0.6'
|
40
41
|
# rubocop:disable Gemspec/RubyVersionGlobalsUsage
|
41
42
|
spec.add_development_dependency(
|
@@ -57,10 +58,10 @@ Gem::Specification.new do |spec|
|
|
57
58
|
|
58
59
|
spec.add_runtime_dependency 'activesupport', '> 4'
|
59
60
|
spec.add_runtime_dependency 'concurrent-ruby', '> 1'
|
60
|
-
spec.add_runtime_dependency 'e2mmap', '
|
61
|
+
spec.add_runtime_dependency 'e2mmap', '>= 0.1'
|
61
62
|
spec.add_runtime_dependency 'grpc', '~> 1.10'
|
62
63
|
spec.add_runtime_dependency 'grpc-tools', '~> 1.10'
|
63
64
|
spec.add_runtime_dependency 'json', '>= 2.3'
|
64
|
-
spec.add_runtime_dependency 'slop', '
|
65
|
-
spec.add_runtime_dependency 'thwait', '
|
65
|
+
spec.add_runtime_dependency 'slop', '>= 4.6'
|
66
|
+
spec.add_runtime_dependency 'thwait', '>= 0.1'
|
66
67
|
end
|
data/lib/gruf/client/error.rb
CHANGED
data/lib/gruf/client.rb
CHANGED
@@ -38,11 +38,14 @@ module Gruf
|
|
38
38
|
class Client < SimpleDelegator
|
39
39
|
include Gruf::Loggable
|
40
40
|
|
41
|
-
#
|
41
|
+
# @!attribute [r] base_klass
|
42
|
+
# @return [Class] The base, friendly name of the service being requested
|
42
43
|
attr_reader :base_klass
|
43
|
-
#
|
44
|
+
# @!attribute [r] service_klass
|
45
|
+
# @return [Class] The class name of the gRPC service being requested
|
44
46
|
attr_reader :service_klass
|
45
|
-
#
|
47
|
+
# @!attribute [r] opts
|
48
|
+
# @return [Hash] A hash of options for the client
|
46
49
|
attr_reader :opts
|
47
50
|
|
48
51
|
##
|
@@ -230,7 +233,7 @@ module Gruf
|
|
230
233
|
GRPC::Core::TimeConsts::ZERO
|
231
234
|
elsif timeout.is_a?(GRPC::Core::TimeSpec)
|
232
235
|
timeout
|
233
|
-
elsif timeout.is_a?(Numeric)
|
236
|
+
elsif timeout.is_a?(Numeric) # rubocop:disable Lint/DuplicateBranch
|
234
237
|
timeout
|
235
238
|
elsif timeout.respond_to?(:to_f)
|
236
239
|
timeout.to_f
|
data/lib/gruf/configuration.rb
CHANGED
@@ -20,6 +20,63 @@ module Gruf
|
|
20
20
|
# Represents configuration settings for the system
|
21
21
|
#
|
22
22
|
module Configuration
|
23
|
+
# @!attribute root_path
|
24
|
+
# @return [String] The root path for your application
|
25
|
+
# @!attribute server_binding_url
|
26
|
+
# @return [String] The full hostname:port that the gRPC server should bind to
|
27
|
+
# @!attribute server_options
|
28
|
+
# @return [Hash] A hash of options to pass to the server instance
|
29
|
+
# @!attribute interceptors
|
30
|
+
# @return [::Gruf::Interceptors::Registry] A registry of Gruf server interceptors
|
31
|
+
# @!attribute hooks
|
32
|
+
# @return [::Gruf::Hooks::Registry] A registry of Gruf hooks for the server
|
33
|
+
# @!attribute default_channel_credentials
|
34
|
+
# @return [NilClass]
|
35
|
+
# @return [Symbol]
|
36
|
+
# @return [Hash]
|
37
|
+
# @!attribute default_client_host
|
38
|
+
# @return [String] The default host for all new Gruf::Client objects to use as their target host
|
39
|
+
# @!attribute use_ssl
|
40
|
+
# @return [Boolean] If true, will setup the server to use TLS
|
41
|
+
# @!attribute ssl_crt_file
|
42
|
+
# @return [String] If use_ssl is true, the relative path from the root_path to the CRT file for the server
|
43
|
+
# @!attribute ssl_key_file
|
44
|
+
# @return [String] If use_ssl is true, the relative path from the root_path to the key file for the server
|
45
|
+
# @!attribute controllers_path
|
46
|
+
# @return [String] The relative path from root_path to locate Gruf Controllers in
|
47
|
+
# @!attribute services
|
48
|
+
# @return [Array<Class>] An array of services to serve with this Gruf server
|
49
|
+
# @!attribute logger
|
50
|
+
# @return [Logger] The logger class for Gruf-based logging
|
51
|
+
# @!attribute grpc_logger
|
52
|
+
# @return [Logger] The logger to use with GRPC's core logger (which logs plaintext). It is recommended to set
|
53
|
+
# this to an STDOUT logger and use a logging pipeline that can translate plaintext logs given GRPC's
|
54
|
+
# unformatted logging.
|
55
|
+
# @!attribute error_metadata_key
|
56
|
+
# @return [Symbol] The metadata key to use for error messages sent back in trailing metadata.
|
57
|
+
# @!attribute error_serializer
|
58
|
+
# @return [NilClass|::Gruf::Serializers::Errors::Base] The error serializer to use for error messages sent
|
59
|
+
# back in trailing metadata. Defaults to the base JSON serializer.
|
60
|
+
# @!attribute append_server_errors_to_trailing_metadata
|
61
|
+
# @return [Boolean] If true, will append all server error information into the trailing metadata in the response
|
62
|
+
# from the server
|
63
|
+
# @!attribute use_default_interceptors
|
64
|
+
# @return [Boolean] If true, will use the default ActiveRecord and Timer interceptors for servers
|
65
|
+
# @!attribute backtrace_on_error
|
66
|
+
# @return [Boolean] If true, will return the backtrace on any errors in servers in the trailing metadata
|
67
|
+
# @!attribute backtrace_limit
|
68
|
+
# @return [Integer] The limit of lines to use in backtraces returned
|
69
|
+
# @!attribute use_exception_message
|
70
|
+
# @return [String] If true, will pass the actual exception message from the error in a server
|
71
|
+
# @!attribute internal_error_message
|
72
|
+
# @return [String] If use_exception_message is false, this message will be used instead as a replacement
|
73
|
+
# @!attribute event_listener_proc
|
74
|
+
# @return [NilClass]
|
75
|
+
# @return [Proc] If set, this will be used during GRPC events (such as pool exhaustions)
|
76
|
+
# @!attribute synchronized_client_internal_cache_expiry
|
77
|
+
# @return [Integer] Internal cache expiry period (in seconds) for the SynchronizedClient
|
78
|
+
# @!attribute rpc_server_options
|
79
|
+
# @return [Hash] A hash of RPC options for GRPC server configuration
|
23
80
|
VALID_CONFIG_KEYS = {
|
24
81
|
root_path: '',
|
25
82
|
server_binding_url: '0.0.0.0:9001',
|
@@ -61,8 +118,8 @@ module Gruf
|
|
61
118
|
# Whenever this is extended into a class, setup the defaults
|
62
119
|
#
|
63
120
|
def self.extended(base)
|
64
|
-
if defined?(Rails)
|
65
|
-
Gruf::Integrations::Rails::Railtie.config.before_initialize { base.reset }
|
121
|
+
if defined?(::Rails)
|
122
|
+
::Gruf::Integrations::Rails::Railtie.config.before_initialize { base.reset }
|
66
123
|
else
|
67
124
|
base.reset
|
68
125
|
end
|
@@ -100,22 +157,28 @@ module Gruf
|
|
100
157
|
VALID_CONFIG_KEYS.each do |k, v|
|
101
158
|
send("#{k}=", v)
|
102
159
|
end
|
103
|
-
self.
|
104
|
-
|
105
|
-
self.
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
require 'logger'
|
110
|
-
self.logger = ::Logger.new($stdout)
|
111
|
-
end
|
112
|
-
self.grpc_logger = logger if grpc_logger.nil?
|
160
|
+
self.server_binding_url = "#{::ENV.fetch('GRPC_SERVER_HOST',
|
161
|
+
'0.0.0.0')}:#{::ENV.fetch('GRPC_SERVER_PORT', 9_001)}"
|
162
|
+
self.interceptors = ::Gruf::Interceptors::Registry.new
|
163
|
+
self.hooks = ::Gruf::Hooks::Registry.new
|
164
|
+
self.root_path = ::Rails.root.to_s.chomp('/') if defined?(::Rails)
|
165
|
+
determine_loggers
|
113
166
|
self.ssl_crt_file = "#{root_path}config/ssl/#{environment}.crt"
|
114
167
|
self.ssl_key_file = "#{root_path}config/ssl/#{environment}.key"
|
115
168
|
self.controllers_path = root_path.to_s.empty? ? 'app/rpc' : "#{root_path}/app/rpc"
|
169
|
+
self.backtrace_on_error = ::ENV.fetch('GRPC_BACKTRACE_ON_ERROR', 0).to_i.positive?
|
170
|
+
self.rpc_server_options = {
|
171
|
+
max_waiting_requests: ::ENV.fetch('GRPC_SERVER_MAX_WAITING_REQUESTS',
|
172
|
+
GRPC::RpcServer::DEFAULT_MAX_WAITING_REQUESTS).to_i,
|
173
|
+
pool_size: ::ENV.fetch('GRPC_SERVER_POOL_SIZE', GRPC::RpcServer::DEFAULT_POOL_SIZE).to_i,
|
174
|
+
pool_keep_alive: ::ENV.fetch('GRPC_SERVER_POOL_KEEP_ALIVE', GRPC::Pool::DEFAULT_KEEP_ALIVE),
|
175
|
+
poll_period: ::ENV.fetch('GRPC_SERVER_POLL_PERIOD', GRPC::RpcServer::DEFAULT_POLL_PERIOD),
|
176
|
+
connect_md_proc: nil,
|
177
|
+
server_args: {}
|
178
|
+
}
|
116
179
|
if use_default_interceptors
|
117
|
-
interceptors.use(Gruf::Interceptors::ActiveRecord::ConnectionReset)
|
118
|
-
interceptors.use(Gruf::Interceptors::Instrumentation::OutputMetadataTimer)
|
180
|
+
interceptors.use(::Gruf::Interceptors::ActiveRecord::ConnectionReset)
|
181
|
+
interceptors.use(::Gruf::Interceptors::Instrumentation::OutputMetadataTimer)
|
119
182
|
end
|
120
183
|
options
|
121
184
|
end
|
@@ -128,11 +191,30 @@ module Gruf
|
|
128
191
|
# @return [String] The current Ruby environment
|
129
192
|
#
|
130
193
|
def environment
|
131
|
-
if defined?(Rails)
|
132
|
-
Rails.env.to_s
|
194
|
+
if defined?(::Rails)
|
195
|
+
::Rails.env.to_s
|
133
196
|
else
|
134
197
|
(ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development').to_s
|
135
198
|
end
|
136
199
|
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Dynamically determine the appropriate logger
|
203
|
+
#
|
204
|
+
def determine_loggers
|
205
|
+
if defined?(::Rails) && ::Rails.logger
|
206
|
+
self.logger = ::Rails.logger
|
207
|
+
else
|
208
|
+
require 'logger'
|
209
|
+
self.logger = ::Logger.new($stdout)
|
210
|
+
log_level = ::ENV.fetch('LOG_LEVEL', 'info').to_s.upcase
|
211
|
+
begin
|
212
|
+
logger.level = ::Logger::Severity.const_get(log_level)
|
213
|
+
rescue NameError => _e
|
214
|
+
logger.level = ::Logger::Severity::INFO
|
215
|
+
end
|
216
|
+
end
|
217
|
+
self.grpc_logger = logger if grpc_logger.nil?
|
218
|
+
end
|
137
219
|
end
|
138
220
|
end
|
@@ -26,13 +26,16 @@ module Gruf
|
|
26
26
|
class Base
|
27
27
|
include Gruf::Errors::Helpers
|
28
28
|
|
29
|
-
#
|
29
|
+
# @!attribute [r] request
|
30
|
+
# @return [Gruf::Controller::Request] The incoming request
|
30
31
|
attr_reader :request
|
31
|
-
#
|
32
|
+
# @!attribute [r] error
|
33
|
+
# @return [Gruf::Error] The current error on the controller
|
32
34
|
attr_reader :error
|
33
35
|
|
34
36
|
class << self
|
35
|
-
#
|
37
|
+
# @!attribute [r] bound_service
|
38
|
+
# @return [GRPC::GenericService] bound_service The bound gRPC service class
|
36
39
|
attr_reader :bound_service
|
37
40
|
end
|
38
41
|
|
@@ -21,15 +21,20 @@ module Gruf
|
|
21
21
|
# Encapsulates a request for a controller
|
22
22
|
#
|
23
23
|
class Request
|
24
|
-
#
|
24
|
+
# @!attribute [r] message
|
25
|
+
# @return [Object] The protobuf message in the request
|
25
26
|
attr_reader :message
|
26
|
-
#
|
27
|
+
# @!attribute [r] active_call
|
28
|
+
# @return [GRPC::ActiveCall] The active call object used for this request
|
27
29
|
attr_reader :active_call
|
28
|
-
#
|
30
|
+
# @!attribute [r] method_key
|
31
|
+
# @return [Symbol] The method name being requested
|
29
32
|
attr_reader :method_key
|
30
|
-
#
|
33
|
+
# @!attribute [r] type
|
34
|
+
# @return [Gruf::Controllers::Request::Type] The type of request
|
31
35
|
attr_reader :type
|
32
|
-
#
|
36
|
+
# @!attribute [r] service
|
37
|
+
# @return [Class] The GRPC service class for this request
|
33
38
|
attr_reader :service
|
34
39
|
|
35
40
|
delegate :metadata, to: :active_call
|
@@ -76,7 +81,7 @@ module Gruf
|
|
76
81
|
# @return [String] The mapped service key
|
77
82
|
#
|
78
83
|
def service_key
|
79
|
-
@service.name.underscore.tr('/', '.').gsub('.service', '')
|
84
|
+
@service.name.to_s.underscore.tr('/', '.').gsub('.service', '')
|
80
85
|
end
|
81
86
|
|
82
87
|
##
|
@@ -106,6 +111,7 @@ module Gruf
|
|
106
111
|
# Return all messages for this request, properly handling different request types
|
107
112
|
#
|
108
113
|
# @return [Enumerable<Object>] All messages for this request
|
114
|
+
# @return [Object] If a bidi streamed request, will return the message object
|
109
115
|
#
|
110
116
|
def messages
|
111
117
|
if client_streamer?
|
data/lib/gruf/error.rb
CHANGED
@@ -59,20 +59,28 @@ module Gruf
|
|
59
59
|
METADATA_SIZE_EXCEEDED_CODE = 'metadata_size_exceeded'
|
60
60
|
METADATA_SIZE_EXCEEDED_MSG = 'Metadata too long, risks exceeding http2 trailing metadata limit.'
|
61
61
|
|
62
|
-
#
|
62
|
+
# @!attribute code
|
63
|
+
# @return [Symbol] The given internal gRPC code for the error
|
63
64
|
attr_accessor :code
|
64
|
-
#
|
65
|
+
# @!attribute app_code
|
66
|
+
# @return [Symbol] An arbitrary application code that can be used for logical processing of the error
|
67
|
+
# by the client
|
65
68
|
attr_accessor :app_code
|
66
|
-
#
|
69
|
+
# @!attribute message
|
70
|
+
# @return [String] The error message returned by the server
|
67
71
|
attr_accessor :message
|
68
|
-
#
|
72
|
+
# @!attribute field_errors
|
73
|
+
# @return [Array] An array of field errors that can be returned by the server
|
69
74
|
attr_accessor :field_errors
|
70
|
-
#
|
71
|
-
#
|
75
|
+
# @!attribute debug_info
|
76
|
+
# @return [Errors::DebugInfo] A object containing debugging information, such as a stack trace and exception name,
|
77
|
+
# that can be used to debug an given error response. This is sent by the server over the trailing metadata.
|
72
78
|
attr_accessor :debug_info
|
73
|
-
#
|
79
|
+
# @!attribute [w] grpc_error
|
80
|
+
# @return [GRPC::BadStatus] The gRPC BadStatus error object that was generated
|
74
81
|
attr_writer :grpc_error
|
75
|
-
#
|
82
|
+
# @!attribute [r] metadata
|
83
|
+
# @return [Hash] The trailing metadata that was attached to the error
|
76
84
|
attr_reader :metadata
|
77
85
|
|
78
86
|
##
|
@@ -21,9 +21,11 @@ module Gruf
|
|
21
21
|
# Represents debugging information for an exception that occurred in a gRPC service
|
22
22
|
#
|
23
23
|
class DebugInfo
|
24
|
-
#
|
24
|
+
# @!attribute [r] detail
|
25
|
+
# @return [String] The detail message of the exception
|
25
26
|
attr_reader :detail
|
26
|
-
#
|
27
|
+
# @!attribute [r] stack_trace
|
28
|
+
# @return [Array<String>] The stack trace generated by the exception as an array of strings
|
27
29
|
attr_reader :stack_trace
|
28
30
|
|
29
31
|
##
|
data/lib/gruf/errors/field.rb
CHANGED
@@ -21,11 +21,14 @@ module Gruf
|
|
21
21
|
# Represents a field-specific error
|
22
22
|
#
|
23
23
|
class Field
|
24
|
-
#
|
24
|
+
# @!attribute [r] field_name
|
25
|
+
# @return [Symbol] The name of the field as a Symbol
|
25
26
|
attr_reader :field_name
|
26
|
-
#
|
27
|
+
# @!attribute [r] error_code
|
28
|
+
# @return [Symbol] The application error code for the field, e.g. :job_not_found
|
27
29
|
attr_reader :error_code
|
28
|
-
#
|
30
|
+
# @!attribute [r] message
|
31
|
+
# @return [String] The error message for the field, e.g. "Job with ID 123 not found"
|
29
32
|
attr_reader :message
|
30
33
|
|
31
34
|
##
|
@@ -21,11 +21,14 @@ module Gruf
|
|
21
21
|
# Base class for interception requests
|
22
22
|
#
|
23
23
|
class Base
|
24
|
-
#
|
24
|
+
# @!attribute [r] request
|
25
|
+
# @return [Gruf::Controllers::Request] request
|
25
26
|
attr_reader :request
|
26
|
-
#
|
27
|
+
# @!attribute [r] error
|
28
|
+
# @return [Gruf::Error] error
|
27
29
|
attr_reader :error
|
28
|
-
#
|
30
|
+
# @!attribute [r] options
|
31
|
+
# @return [Hash] options
|
29
32
|
attr_reader :options
|
30
33
|
|
31
34
|
##
|
@@ -28,8 +28,12 @@ module Gruf
|
|
28
28
|
# @property [Float] elapsed The elapsed time of the request
|
29
29
|
#
|
30
30
|
class Result
|
31
|
-
|
32
|
-
|
31
|
+
# @!attribute [r] message
|
32
|
+
# @return [Object] The returned protobuf message
|
33
|
+
attr_reader :message
|
34
|
+
# @return [r] elapsed
|
35
|
+
# @return [Float] The time elapsed for this interceptor to execute
|
36
|
+
attr_reader :elapsed
|
33
37
|
|
34
38
|
##
|
35
39
|
# @param [Object] message The protobuf message
|
@@ -53,7 +57,7 @@ module Gruf
|
|
53
57
|
# @return [String] The name of the message class
|
54
58
|
#
|
55
59
|
def message_class_name
|
56
|
-
@message.class.name
|
60
|
+
@message.class.name.to_s
|
57
61
|
end
|
58
62
|
|
59
63
|
##
|
@@ -21,15 +21,20 @@ module Gruf
|
|
21
21
|
# Encapsulates the context of an outbound client request
|
22
22
|
#
|
23
23
|
class RequestContext
|
24
|
-
#
|
24
|
+
# @!attribute [r] type
|
25
|
+
# @return [Symbol]
|
25
26
|
attr_reader :type
|
26
|
-
#
|
27
|
+
# @!attribute [r] requests
|
28
|
+
# @return [Enumerable] requests
|
27
29
|
attr_reader :requests
|
28
|
-
#
|
30
|
+
# @!attribute [r] call
|
31
|
+
# @return [GRPC::ActiveCall]
|
29
32
|
attr_reader :call
|
30
|
-
#
|
33
|
+
# @!attribute [r] method
|
34
|
+
# @return [Method] method
|
31
35
|
attr_reader :method
|
32
|
-
#
|
36
|
+
# @!attribute [r] metadata
|
37
|
+
# @return [Hash] metadata
|
33
38
|
attr_reader :metadata
|
34
39
|
|
35
40
|
##
|
@@ -55,7 +60,7 @@ module Gruf
|
|
55
60
|
# @return [String]
|
56
61
|
#
|
57
62
|
def method_name
|
58
|
-
@method.to_s.split('/').last
|
63
|
+
@method.to_s.split('/').last.to_s
|
59
64
|
end
|
60
65
|
|
61
66
|
##
|
@@ -64,7 +69,7 @@ module Gruf
|
|
64
69
|
# @return [String]
|
65
70
|
#
|
66
71
|
def route_key
|
67
|
-
@method[1..].underscore.tr('/', '.')
|
72
|
+
@method[1..].to_s.underscore.tr('/', '.')
|
68
73
|
end
|
69
74
|
end
|
70
75
|
end
|
data/lib/gruf/response.rb
CHANGED
@@ -20,17 +20,23 @@ module Gruf
|
|
20
20
|
# Wraps the active call operation to provide metadata and timing around the request
|
21
21
|
#
|
22
22
|
class Response
|
23
|
-
#
|
23
|
+
# @!attribute [r] operation
|
24
|
+
# @return [GRPC::ActiveCall::Operation] The operation that was executed for the given request
|
24
25
|
attr_reader :operation
|
25
|
-
#
|
26
|
+
# @!attribute [r] metadata
|
27
|
+
# @return [Hash] The metadata that was attached to the operation
|
26
28
|
attr_reader :metadata
|
27
|
-
#
|
29
|
+
# @!attribute [r] trailing_metadata
|
30
|
+
# @return [Hash] The trailing metadata that the service returned
|
28
31
|
attr_reader :trailing_metadata
|
29
|
-
#
|
32
|
+
# @!attribute [r] deadline
|
33
|
+
# @return [Time] The set deadline on the call
|
30
34
|
attr_reader :deadline
|
31
|
-
#
|
35
|
+
# @!attribute [r] cancelled
|
36
|
+
# @return [Boolean] Whether or not the operation was cancelled
|
32
37
|
attr_reader :cancelled
|
33
|
-
#
|
38
|
+
# @!attribute [r] execution_time
|
39
|
+
# @return [Float] The time that the request took to execute
|
34
40
|
attr_reader :execution_time
|
35
41
|
|
36
42
|
##
|
@@ -22,7 +22,8 @@ module Gruf
|
|
22
22
|
# Base class for serialization of errors for transport across the grpc protocol
|
23
23
|
#
|
24
24
|
class Base
|
25
|
-
#
|
25
|
+
# @!attribute [r] error
|
26
|
+
# @return [Gruf::Error|String] The error being serialized
|
26
27
|
attr_reader :error
|
27
28
|
|
28
29
|
##
|
data/lib/gruf/server.rb
CHANGED
@@ -23,11 +23,15 @@ module Gruf
|
|
23
23
|
class Server
|
24
24
|
class ServerAlreadyStartedError < StandardError; end
|
25
25
|
|
26
|
+
KILL_SIGNALS = %w[INT TERM QUIT].freeze
|
27
|
+
|
26
28
|
include Gruf::Loggable
|
27
29
|
|
28
|
-
#
|
30
|
+
# @!attribute [r] port
|
31
|
+
# @return [Integer] The port the server is bound to
|
29
32
|
attr_reader :port
|
30
|
-
#
|
33
|
+
# @!attribute [r] options
|
34
|
+
# @return [Hash] Hash of options passed into the server
|
31
35
|
attr_reader :options
|
32
36
|
|
33
37
|
##
|
@@ -41,10 +45,6 @@ module Gruf
|
|
41
45
|
@interceptors = Gruf::Interceptors::Registry.new unless @interceptors.is_a?(Gruf::Interceptors::Registry)
|
42
46
|
@services = []
|
43
47
|
@started = false
|
44
|
-
@stop_server = false
|
45
|
-
@stop_server_cv = ConditionVariable.new
|
46
|
-
@stop_server_mu = Monitor.new
|
47
|
-
@server_mu = Monitor.new
|
48
48
|
@hostname = opts.fetch(:hostname, Gruf.server_binding_url)
|
49
49
|
@event_listener_proc = opts.fetch(:event_listener_proc, Gruf.event_listener_proc)
|
50
50
|
setup
|
@@ -54,30 +54,28 @@ module Gruf
|
|
54
54
|
# @return [GRPC::RpcServer] The GRPC server running
|
55
55
|
#
|
56
56
|
def server
|
57
|
-
@
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
server
|
80
|
-
end
|
57
|
+
@server ||= begin
|
58
|
+
# For backward compatibility, we allow these options to be passed directly
|
59
|
+
# in the Gruf::Server options, or via Gruf.rpc_server_options.
|
60
|
+
server_options = {
|
61
|
+
pool_size: options.fetch(:pool_size, Gruf.rpc_server_options[:pool_size]),
|
62
|
+
max_waiting_requests: options.fetch(:max_waiting_requests, Gruf.rpc_server_options[:max_waiting_requests]),
|
63
|
+
poll_period: options.fetch(:poll_period, Gruf.rpc_server_options[:poll_period]),
|
64
|
+
pool_keep_alive: options.fetch(:pool_keep_alive, Gruf.rpc_server_options[:pool_keep_alive]),
|
65
|
+
connect_md_proc: options.fetch(:connect_md_proc, Gruf.rpc_server_options[:connect_md_proc]),
|
66
|
+
server_args: options.fetch(:server_args, Gruf.rpc_server_options[:server_args])
|
67
|
+
}
|
68
|
+
|
69
|
+
server = if @event_listener_proc
|
70
|
+
server_options[:event_listener_proc] = @event_listener_proc
|
71
|
+
Gruf::InstrumentableGrpcServer.new(**server_options)
|
72
|
+
else
|
73
|
+
GRPC::RpcServer.new(**server_options)
|
74
|
+
end
|
75
|
+
|
76
|
+
@port = server.add_http2_port(@hostname, ssl_credentials)
|
77
|
+
@services.each { |s| server.handle(s) }
|
78
|
+
server
|
81
79
|
end
|
82
80
|
end
|
83
81
|
|
@@ -90,23 +88,10 @@ module Gruf
|
|
90
88
|
|
91
89
|
server_thread = Thread.new do
|
92
90
|
logger.info { "Starting gruf server at #{@hostname}..." }
|
93
|
-
server.
|
94
|
-
end
|
95
|
-
|
96
|
-
stop_server_thread = Thread.new do
|
97
|
-
loop do
|
98
|
-
break if @stop_server
|
99
|
-
|
100
|
-
@stop_server_mu.synchronize { @stop_server_cv.wait(@stop_server_mu, 10) }
|
101
|
-
end
|
102
|
-
logger.info { 'Shutting down...' }
|
103
|
-
server.stop
|
91
|
+
server.run_till_terminated_or_interrupted(KILL_SIGNALS)
|
104
92
|
end
|
105
|
-
|
106
|
-
server.wait_till_running
|
107
93
|
@started = true
|
108
94
|
update_proc_title(:serving)
|
109
|
-
stop_server_thread.join
|
110
95
|
server_thread.join
|
111
96
|
@started = false
|
112
97
|
|
@@ -202,28 +187,10 @@ module Gruf
|
|
202
187
|
#
|
203
188
|
# :nocov:
|
204
189
|
def setup
|
205
|
-
setup_signal_handlers
|
206
190
|
load_controllers
|
207
191
|
end
|
208
192
|
# :nocov:
|
209
193
|
|
210
|
-
##
|
211
|
-
# Register signal handlers
|
212
|
-
#
|
213
|
-
# :nocov:
|
214
|
-
def setup_signal_handlers
|
215
|
-
Signal.trap('INT') do
|
216
|
-
@stop_server = true
|
217
|
-
@stop_server_cv.broadcast
|
218
|
-
end
|
219
|
-
|
220
|
-
Signal.trap('TERM') do
|
221
|
-
@stop_server = true
|
222
|
-
@stop_server_cv.broadcast
|
223
|
-
end
|
224
|
-
end
|
225
|
-
# :nocov:
|
226
|
-
|
227
194
|
##
|
228
195
|
# Auto-load all gRPC handlers
|
229
196
|
#
|
data/lib/gruf/timer.rb
CHANGED
@@ -33,8 +33,12 @@ module Gruf
|
|
33
33
|
# @property [Float] time The time, in ms, of the block execution
|
34
34
|
#
|
35
35
|
class Result
|
36
|
-
|
37
|
-
|
36
|
+
# @!attribute [r] result
|
37
|
+
# @return [mixed]
|
38
|
+
attr_reader :result
|
39
|
+
# @!attribute [r] time
|
40
|
+
# @return [Float]
|
41
|
+
attr_reader :time
|
38
42
|
|
39
43
|
##
|
40
44
|
# Initialize the result object
|
data/lib/gruf/version.rb
CHANGED
data/lib/gruf.rb
CHANGED
@@ -40,7 +40,7 @@ require_relative 'gruf/client'
|
|
40
40
|
require_relative 'gruf/synchronized_client'
|
41
41
|
require_relative 'gruf/instrumentable_grpc_server'
|
42
42
|
require_relative 'gruf/server'
|
43
|
-
require_relative 'gruf/integrations/rails/railtie' if defined?(Rails)
|
43
|
+
require_relative 'gruf/integrations/rails/railtie' if defined?(::Rails)
|
44
44
|
|
45
45
|
##
|
46
46
|
# Initializes configuration of gruf core module
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gruf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun McCormick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.11'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.11'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler-audit
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,14 +224,14 @@ dependencies:
|
|
238
224
|
name: e2mmap
|
239
225
|
requirement: !ruby/object:Gem::Requirement
|
240
226
|
requirements:
|
241
|
-
- - "
|
227
|
+
- - ">="
|
242
228
|
- !ruby/object:Gem::Version
|
243
229
|
version: '0.1'
|
244
230
|
type: :runtime
|
245
231
|
prerelease: false
|
246
232
|
version_requirements: !ruby/object:Gem::Requirement
|
247
233
|
requirements:
|
248
|
-
- - "
|
234
|
+
- - ">="
|
249
235
|
- !ruby/object:Gem::Version
|
250
236
|
version: '0.1'
|
251
237
|
- !ruby/object:Gem::Dependency
|
@@ -294,28 +280,28 @@ dependencies:
|
|
294
280
|
name: slop
|
295
281
|
requirement: !ruby/object:Gem::Requirement
|
296
282
|
requirements:
|
297
|
-
- - "
|
283
|
+
- - ">="
|
298
284
|
- !ruby/object:Gem::Version
|
299
285
|
version: '4.6'
|
300
286
|
type: :runtime
|
301
287
|
prerelease: false
|
302
288
|
version_requirements: !ruby/object:Gem::Requirement
|
303
289
|
requirements:
|
304
|
-
- - "
|
290
|
+
- - ">="
|
305
291
|
- !ruby/object:Gem::Version
|
306
292
|
version: '4.6'
|
307
293
|
- !ruby/object:Gem::Dependency
|
308
294
|
name: thwait
|
309
295
|
requirement: !ruby/object:Gem::Requirement
|
310
296
|
requirements:
|
311
|
-
- - "
|
297
|
+
- - ">="
|
312
298
|
- !ruby/object:Gem::Version
|
313
299
|
version: '0.1'
|
314
300
|
type: :runtime
|
315
301
|
prerelease: false
|
316
302
|
version_requirements: !ruby/object:Gem::Requirement
|
317
303
|
requirements:
|
318
|
-
- - "
|
304
|
+
- - ">="
|
319
305
|
- !ruby/object:Gem::Version
|
320
306
|
version: '0.1'
|
321
307
|
description: gRPC Ruby Framework for building complex gRPC applications at scale
|
@@ -376,7 +362,8 @@ files:
|
|
376
362
|
homepage: https://github.com/bigcommerce/gruf
|
377
363
|
licenses:
|
378
364
|
- MIT
|
379
|
-
metadata:
|
365
|
+
metadata:
|
366
|
+
rubygems_mfa_required: 'true'
|
380
367
|
post_install_message:
|
381
368
|
rdoc_options: []
|
382
369
|
require_paths:
|
@@ -395,7 +382,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
395
382
|
- !ruby/object:Gem::Version
|
396
383
|
version: '0'
|
397
384
|
requirements: []
|
398
|
-
rubygems_version: 3.
|
385
|
+
rubygems_version: 3.3.4
|
399
386
|
signing_key:
|
400
387
|
specification_version: 4
|
401
388
|
summary: gRPC Ruby Framework
|