gruf 1.2.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +98 -119
  4. data/bin/gruf +9 -3
  5. data/lib/gruf.rb +4 -4
  6. data/lib/gruf/configuration.rb +11 -20
  7. data/lib/gruf/controllers/base.rb +82 -0
  8. data/lib/gruf/controllers/request.rb +96 -0
  9. data/lib/gruf/controllers/service_binder.rb +86 -0
  10. data/lib/gruf/error.rb +9 -0
  11. data/lib/gruf/errors/helpers.rb +40 -0
  12. data/lib/gruf/{hooks → interceptors}/active_record/connection_reset.rb +4 -10
  13. data/lib/gruf/interceptors/authentication/basic.rb +80 -0
  14. data/lib/gruf/interceptors/base.rb +51 -0
  15. data/lib/gruf/{instrumentation/output_metadata_timer.rb → interceptors/context.rb} +25 -15
  16. data/lib/gruf/interceptors/instrumentation/output_metadata_timer.rb +59 -0
  17. data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/base.rb +15 -13
  18. data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/logstash.rb +15 -13
  19. data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/plain.rb +21 -19
  20. data/lib/gruf/interceptors/instrumentation/request_logging/interceptor.rb +191 -0
  21. data/lib/gruf/interceptors/instrumentation/statsd.rb +80 -0
  22. data/lib/gruf/interceptors/registry.rb +131 -0
  23. data/lib/gruf/{authentication/none.rb → interceptors/server_interceptor.rb} +8 -7
  24. data/lib/gruf/interceptors/timer.rb +79 -0
  25. data/lib/gruf/response.rb +1 -2
  26. data/lib/gruf/server.rb +40 -25
  27. data/lib/gruf/version.rb +1 -1
  28. metadata +19 -20
  29. data/lib/gruf/authentication.rb +0 -65
  30. data/lib/gruf/authentication/base.rb +0 -65
  31. data/lib/gruf/authentication/basic.rb +0 -74
  32. data/lib/gruf/authentication/strategies.rb +0 -107
  33. data/lib/gruf/hooks/base.rb +0 -66
  34. data/lib/gruf/hooks/registry.rb +0 -110
  35. data/lib/gruf/instrumentation/base.rb +0 -114
  36. data/lib/gruf/instrumentation/registry.rb +0 -104
  37. data/lib/gruf/instrumentation/request_context.rb +0 -82
  38. data/lib/gruf/instrumentation/request_logging/hook.rb +0 -185
  39. data/lib/gruf/instrumentation/statsd.rb +0 -80
  40. data/lib/gruf/service.rb +0 -333
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8494cc65922d13e3d9d70f0eeed43cb54cec22b0
4
- data.tar.gz: e0afec068276451c09ad350d23ca165becb552b0
3
+ metadata.gz: d589a46b3a36a065a4844e937c177cdf662a19db
4
+ data.tar.gz: 412c889f35ded87f6a14990f79d25d2a6f5c9323
5
5
  SHA512:
6
- metadata.gz: 6a783314fd5761fed60ee87426cb1d1aa78d515fc447232b88470a4b73e69b3f5102119f13cb6cea53086a45ef257d461aa467cc38a2dc09f3270b04e9638479
7
- data.tar.gz: 2adc8447c02b004a67c06eb9d73b439afd00d1db1750046f4edbeb933686a737da82813fa71b16d4f087279056fb33c1dae821b5f98c9b19fd315a445be16dd8
6
+ metadata.gz: e80f4936341779ddda0c09c844a97f578c4c738be8c6db55156a4e35af931f4eae87d050906673d3fa141f05d2e0a869f12e2fbe156fc57ad996be31fc896c47
7
+ data.tar.gz: 78e4ac11542cc8cbc647f68657f1571ee27aa7a7c125e80fb6d8b4d148226e47c9030d3dd2780b4735700bb5bb0744333909d72f75a26a8d7961049bdaa8df8e
@@ -2,6 +2,17 @@ Changelog for the gruf gem. This includes internal history before the gem was ma
2
2
 
3
3
  ### Pending release
4
4
 
5
+ ### 2.0.0
6
+
7
+ Gruf 2.0 is a major shift from Gruf 1.0. See [UPGRADING.md](UPGRADING.md) for details.
8
+
9
+ - New thread-safe controller-based model
10
+ - New controller request object
11
+ - Hooks deprecated in favor of interceptors
12
+ - New interceptor timer utility class
13
+ - Default logging to logstash formatter
14
+ - Various Gruf::Server improvements
15
+
5
16
  ### 1.2.7
6
17
 
7
18
  - Fix issues where field errors were persisted in between separate calls
data/README.md CHANGED
@@ -8,17 +8,18 @@ provide a more streamlined integration into Ruby and Ruby on Rails applications.
8
8
  It provides an abstracted server and client for gRPC services, along with other tools to help get gRPC services in Ruby
9
9
  up fast and efficiently at scale. Some of its features include:
10
10
 
11
- * Abstracted server endpoints with before, around, outer around, and after hooks during an endpoint call
11
+ * Abstracted controllers with request context support
12
+ * Full interceptors with timing and unified request context support
12
13
  * Robust client error handling and metadata transport abilities
13
- * Server authentication strategy support, with basic auth with multiple key support built in
14
+ * Server authentication via interceptors, with basic auth with multiple key support built in
14
15
  * TLS support for client-server auth, though we recommend using [linkerd](https://linkerd.io/) instead
15
- * Error data serialization in output metadata to allow fine-grained error handling in the transport while still
16
- preserving gRPC BadStatus codes
16
+ * Error data serialization in output metadata to allow fine-grained error handling in the transport while
17
+ still preserving gRPC BadStatus codes
17
18
  * Server and client execution timings in responses
18
19
 
19
- gruf currently has active support for gRPC 1.4.x. gruf is compatible and tested with with Ruby 2.2, 2.3, and 2.4. gruf
20
- is also not [Rails](https://github.com/rails/rails)-specific, and can be used in any Ruby framework (such as
21
- [Grape](https://github.com/ruby-grape/grape), for instance).
20
+ gruf currently has active support for gRPC 1.4.x-1.6.x. gruf is compatible and tested with Ruby 2.2,
21
+ 2.3, and 2.4. gruf is also not [Rails](https://github.com/rails/rails)-specific, and can be used in any
22
+ Ruby framework (such as [Grape](https://github.com/ruby-grape/grape), for instance).
22
23
 
23
24
  ## Installation
24
25
 
@@ -89,26 +90,22 @@ message GetJobResp {
89
90
  }
90
91
  ```
91
92
 
92
- You'd have this handler in `/app/rpc/demo/job_server.rb`
93
+ You'd have this handler in `/app/rpc/demo/job_controller.rb`
93
94
 
94
95
  ```ruby
95
96
  module Demo
96
- class JobServer < ::Demo::Jobs::Service
97
- include Gruf::Service
97
+ class JobController < ::Gruf::Controllers::Base
98
+ bind ::Demo::Jobs::Service
98
99
 
99
100
  ##
100
- # @param [Demo::GetJobReq] req The incoming gRPC request object
101
- # @param [GRPC::ActiveCall] call The gRPC active call instance
102
101
  # @return [Demo::GetJobResp] The job response
103
102
  #
104
- def get_job(req, call)
105
- thing = Job.find(req.id)
103
+ def get_job
104
+ thing = Job.find(request.message.id)
106
105
 
107
- Demo::GetJobResp.new(
108
- id: thing.id
109
- )
106
+ Demo::GetJobResp.new(id: thing.id)
110
107
  rescue
111
- fail!(req, call, :not_found, :job_not_found, "Failed to find Job with ID: #{req.id}")
108
+ fail!(:not_found, :job_not_found, "Failed to find Job with ID: #{request.message.id}")
112
109
  end
113
110
  end
114
111
  end
@@ -118,35 +115,15 @@ Finally, you can start the server by running:
118
115
 
119
116
  bundle exec gruf
120
117
 
121
- ### Authentication
118
+ ### Basic Authentication
122
119
 
123
- Authentication is done via a strategy pattern and are injectable via middleware. If any of the strategies return `true`,
124
- it will proceed the request as successful. For example, to add basic auth, you can do:
120
+ Gruf comes packaged in with a Basic Authentication interceptor. It takes in an array of supported
121
+ username and password pairs (or password-only credentials).
125
122
 
126
123
  ```ruby
127
- Gruf::Authentication::Strategies.add(:basic, Gruf::Authentication::Basic)
128
- ```
129
-
130
- Options to the middleware libraries can be passed through the `authentication_options` configuration option.
131
-
132
- To add a custom authentication pattern, your class must extend the `Gruf::Authentication::Base` class, and implement
133
- the `valid?(call)` method. For example, this class allows everyone in:
134
-
135
- ```
136
- class NoAuth < Gruf::Authentication::Base
137
- def valid?(_call)
138
- true
139
- end
140
- end
141
- ```
142
-
143
- #### Basic Auth
144
-
145
- gruf supports simple basic authentication with an array of accepted credentials:
146
-
147
- ```ruby
148
- Gruf.configure do |c|
149
- c.authentication_options = {
124
+ Gruf.configure do |c|
125
+ c.interceptors.use(
126
+ Gruf::Instrumentation::Authentication::Basic,
150
127
  credentials: [{
151
128
  username: 'my-username-here',
152
129
  password: 'my-password-here',
@@ -156,12 +133,12 @@ Gruf.configure do |c|
156
133
  },{
157
134
  password: 'a-password-only'
158
135
  }]
159
- }
136
+ )
160
137
  end
161
138
  ```
162
139
 
163
- Supporting an array of credentials allow for unique credentials per service, or for easy credential rotation with
164
- zero downtime.
140
+ Supporting an array of credentials allow for unique credentials per service, or for easy credential
141
+ rotation with zero downtime.
165
142
 
166
143
  ### SSL Configuration
167
144
 
@@ -189,90 +166,88 @@ Gruf.configure do |c|
189
166
  end
190
167
  ```
191
168
 
192
- ## Hooks
169
+ ## Server Interceptors
193
170
 
194
- gruf supports hooks that act as interceptors around the grpc server calls, allowing you to perform actions before,
195
- after, and even around your server endpoints. This can be used to add tracing data, connection resets in the grpc thread
196
- pool, further instrumentation, and other things.
171
+ gruf supports interceptors around the grpc server calls, allowing you to perform actions around your service
172
+ method calls. This can be used to add tracing data, connection resets in the grpc thread pool, further
173
+ instrumentation, and other things.
197
174
 
198
- Adding a hook is as simple as creating a class that extends `Gruf::Hooks::Base`, and implementing it via the registry.
175
+ Adding a hook is as simple as creating a class that extends `Gruf::Interceptor::ServerInterceptor`,
176
+ and a `call` method that yields control to get the method result:
199
177
 
200
- ### Before
201
-
202
- A before hook passes in the method call signature, request object, and `GRPC::ActiveCall` object:
203
178
  ```ruby
204
- class MyBeforeHook < Gruf::Hooks::Base
205
- def before(call_signature, request, active_call)
206
- # do my thing before the call. Calling `fail!` here will prevent the call from happening.
179
+ class MyInterceptor < ::Gruf::Interceptors::ServerInterceptor
180
+ def call
181
+ yield
207
182
  end
208
183
  end
209
- Gruf::Hooks::Registry.add(:my_before_hook, MyBeforeHook)
210
184
  ```
211
185
 
212
- ### After
186
+ Interceptors have access to the `request` object, which is the `Gruf::Controller::Request` object
187
+ described above.
213
188
 
214
- An after hook passes in the response object, method call signature, request object, and `GRPC::ActiveCall` object:
215
- ```ruby
216
- class MyAfterHook < Gruf::Hooks::Base
217
- def after(success, response, call_signature, request, active_call)
218
- # You can modify the response object
219
- end
220
- end
221
- Gruf::Hooks::Registry.add(:my_after_hook, MyAfterHook)
222
- ```
189
+ ### Failing in an Interceptor
223
190
 
224
- ### Around
191
+ Interceptors can fail requests with the same method calls as a controller:
225
192
 
226
- An around hook passes in the method call signature, request object, `GRPC::ActiveCall` object, and the block
227
- being executed:
228
193
  ```ruby
229
- class MyAroundHook < Gruf::Hooks::Base
230
- def around(call_signature, request, active_call, &block)
231
- # do my thing here
232
- resp = yield
233
- # do my thing there
234
- resp
194
+ class MyFailingInterceptor < ::Gruf::Interceptors::ServerInterceptor
195
+ def call
196
+ result = yield # this returns the protobuf message
197
+ unless result.dont_hijack
198
+ # we'll assume this "dont_hijack" attribute exists on the message for this example
199
+ fail!(:internal, :hijacked, 'Hijack all the things!')
200
+ end
201
+ result
235
202
  end
236
203
  end
237
- Gruf::Hooks::Registry.add(:my_around_hook, MyAroundHook)
238
204
  ```
239
205
 
240
- Around hooks are a special case - because each needs to wrap the call, they are run recursively within each other.
241
- This means that if you have three hooks - `Hook1`, `Hook2`, and `Hook3` - they will run in LIFO (last in, first out)
242
- order. `Hook3` will run, calling `Hook2`, which will then call `Hook1`, ending the chain.
206
+ Similarly, you can raise `GRPC::BadStatus` calls to trigger similar errors without accompanying metadata.
243
207
 
244
- ### Outer Around
208
+ ### Configuring Interceptors
245
209
 
246
- And finally, an "outer" around hook passes in the method call signature, request object, `GRPC::ActiveCall`
247
- object, and the block being executed, and executes around the _entire_ call chain (before, around, request, after):
210
+ From there, the interceptor can be added to the server manually (if not executing via `bundle exec gruf`):
248
211
 
249
212
  ```ruby
250
- class MyOuterAroundHook < Gruf::Hooks::Base
251
- def outer_around(call_signature, request, active_call, &block)
252
- # do my thing here
253
- resp = yield
254
- # do my thing there
255
- resp
256
- end
213
+ server = Gruf::Server.new
214
+ server.add_interceptor(MyInterceptor, option_foo: 'value 123')
215
+ ```
216
+
217
+ Or, alternatively, the more common method of passing them into the `interceptors` configuration hash:
218
+
219
+ ```ruby
220
+ Gruf.configure do |c|
221
+ c.interceptors.use(MyInterceptor, option_foo: 'value 123')
257
222
  end
258
- Gruf::Hooks::Registry.add(:my_outer_around_hook, MyOuterAroundHook)
259
223
  ```
260
224
 
261
- Outer around hooks behave similarly in execution order to around hooks.
225
+ Interceptors each wrap the call and are run recursively within each other. This means that if you have
226
+ three interceptors - `Interceptor1`, `Interceptor2`, and `Interceptor3` - they will run in FIFO
227
+ (first in, first out) order. `Interceptor1` will run, yielding to `Interceptor2`,
228
+ which will then yield to `Interceptor3`, which will then yield to your service method call,
229
+ ending the chain.
262
230
 
263
- Note: It's important to note that the authentication step happens immediately before the first _before_ hook is called,
264
- so don't perform any actions that you want behind authentication in outer around hooks, as they are not called with
265
- authentication.
231
+ You can utilize the `insert_before` and `insert_after` methods to maintain order:
232
+
233
+ ```ruby
234
+ Gruf.configure do |c|
235
+ c.interceptors.use(Interceptor1)
236
+ c.interceptors.use(Interceptor2)
237
+ c.interceptors.insert_before(Interceptor2, Interceptor3) # 3 will now happen before 2
238
+ c.interceptors.insert_after(Interceptor1, Interceptor4) # 4 will now happen after 1
239
+ end
240
+ ```
266
241
 
267
242
  ## Instrumentation
268
243
 
269
- gruf comes out of the box with a couple of instrumentors packed in: output metadata timings, and StatsD
270
- support.
244
+ gruf comes out of the box with a couple of instrumentation interceptors packed in:
245
+ output metadata timings and StatsD support.
271
246
 
272
247
  ### Output Metadata Timing
273
248
 
274
- Enabled by default, this will push timings for _successful responses_ through the response output metadata back to the
275
- client.
249
+ Enabled by default, this will push timings for _successful responses_ through the response output
250
+ metadata back to the client.
276
251
 
277
252
  ### StatsD
278
253
 
@@ -280,22 +255,20 @@ The StatsD support is not enabled by default. To enable it, you'll want to do:
280
255
 
281
256
  ```ruby
282
257
  Gruf.configure do |c|
283
- c.instrumentation_options[:statsd] = {
258
+ c.interceptors.use(
259
+ Gruf::Interceptors::Instrumentation::Statsd,
284
260
  client: ::Statsd.new('my.statsd.host', 8125),
285
261
  prefix: 'my_application_prefix.rpc'
286
- }
262
+ )
287
263
  end
288
- Gruf::Instrumentation::Registry.add(:statsd, Gruf::Instrumentation::Statsd)
289
264
  ```
290
265
 
291
- This will measure counts and timings for each endpoint. Note: instrumentation hooks happen in LIFO order; they also
292
- run similarly to an outer_around hook, executing _before_ authorization happens. Note: It's important that in your
293
- instrumentors, you pass-through exceptions (such as `GRPC::BadStatus`); catching them in instrumentors will cause errors
294
- upstream.
266
+ This will measure counts and timings for each endpoint.
295
267
 
296
268
  ### Request Logging
297
269
 
298
- Gruf 1.2+ comes built with request logging out of the box; you'll get Rails-style logs with your gRPC calls:
270
+ Gruf 1.2+ comes built with request logging out of the box; you'll get Rails-style logs with your
271
+ gRPC calls:
299
272
 
300
273
  ```
301
274
  # plain
@@ -308,9 +281,10 @@ It supports formatters (including custom ones) that you can use to specify the f
308
281
 
309
282
  ```ruby
310
283
  Gruf.configure do |c|
311
- c.instrumentation_options[:request_logging] = {
284
+ c.interceptors.use(
285
+ Gruf::Interceptors::Instrumentation::RequestLogging::Interceptor,
312
286
  formatter: :logstash
313
- }
287
+ )
314
288
  end
315
289
  ```
316
290
 
@@ -318,7 +292,7 @@ It comes with a few more options as well:
318
292
 
319
293
  | Option | Description | Default |
320
294
  | ------ | ----------- | ------- |
321
- | formatter | The formatter to use. By default `:plain` and `:logstash` are supported. | `:plain` |
295
+ | formatter | The formatter to use. By default `:plain` and `:logstash` are supported. | `:logstash` |
322
296
  | log_parameters | If set to true, will log parameters in the response | `false` |
323
297
  | blacklist | An array of parameter key names to redact from logging, in path.to.key format | `[]` |
324
298
  | redacted_string | The string to use for redacted parameters. | `REDACTED` |
@@ -327,11 +301,6 @@ It's important to maintain a safe blacklist should you decide to log parameters;
327
301
  parameter sanitization on its own. We also recommend blacklisting parameters that may contain
328
302
  very large values (such as binary or json data).
329
303
 
330
- ### Custom Instrumentors
331
-
332
- Similar to hooks, simply extend the `Gruf::Instrumentation::Base` class, and implement the `call` method. See the StatsD
333
- instrumentor for an example.
334
-
335
304
  ## Plugins
336
305
 
337
306
  You can build your own hooks and middleware for gruf; here's a list of known open source gems for
@@ -346,8 +315,18 @@ reports for gruf services
346
315
 
347
316
  ## Demo Rails App
348
317
 
349
- There is a [demonstration Rails application here](https://github.com/bigcommerce/gruf-demo) you can view and clone
350
- that shows how to integrate Gruf into an existing Rails application.
318
+ There is a [demonstration Rails application here](https://github.com/bigcommerce/gruf-demo) you can
319
+ view and clone that shows how to integrate Gruf into an existing Rails application.
320
+
321
+ ## Roadmap
322
+
323
+ ### Gruf 3.0
324
+
325
+ * Utilize the new core Ruby interceptors in gRPC 1.7
326
+ * Change configuration to an injectable object to ensure thread safety on chained server/client interactions
327
+ * Move all references to `Gruf.` configuration into injectable parameters
328
+ * Redo server configuration to be fully injectable
329
+ * Move client calls to their native method implementation
351
330
 
352
331
  ## License
353
332
 
data/bin/gruf CHANGED
@@ -17,13 +17,19 @@
17
17
  #
18
18
  require 'rubygems'
19
19
  require 'bundler/setup'
20
- require 'gruf'
21
20
  require 'rails' rescue nil
22
21
  load 'config/environment.rb' if defined?(Rails)
22
+ require 'gruf'
23
23
 
24
24
  begin
25
- server = Gruf::Server.new
25
+ server = Gruf::Server.new(Gruf.server_options)
26
+ Gruf.services.each { |s| server.add_service(s) }
26
27
  server.start!
27
28
  rescue => e
28
- Gruf.logger.fatal "FATAL ERROR: #{e.message} #{e.backtrace.join("\n")}"
29
+ msg = "FATAL ERROR: #{e.message} #{e.backtrace.join("\n")}"
30
+ if Gruf.logger
31
+ Gruf.logger.fatal msg
32
+ else
33
+ Logger.new(STDOUT).fatal msg
34
+ end
29
35
  end
@@ -23,10 +23,10 @@ require_relative 'gruf/version'
23
23
  require_relative 'gruf/logging'
24
24
  require_relative 'gruf/loggable'
25
25
  require_relative 'gruf/configuration'
26
- require_relative 'gruf/authentication'
27
- require_relative 'gruf/hooks/registry'
28
- require_relative 'gruf/instrumentation/registry'
29
- require_relative 'gruf/service'
26
+ require_relative 'gruf/errors/helpers'
27
+ require_relative 'gruf/controllers/base'
28
+ require_relative 'gruf/interceptors/registry'
29
+ require_relative 'gruf/interceptors/base'
30
30
  require_relative 'gruf/timer'
31
31
  require_relative 'gruf/response'
32
32
  require_relative 'gruf/error'
@@ -23,22 +23,19 @@ module Gruf
23
23
  root_path: '',
24
24
  server_binding_url: '0.0.0.0:9001',
25
25
  server_options: {},
26
- authentication_options: {},
27
- instrumentation_options: {},
28
- hook_options: {},
26
+ interceptors: nil,
29
27
  default_client_host: '',
30
28
  use_ssl: false,
31
29
  ssl_crt_file: '',
32
30
  ssl_key_file: '',
33
- servers_path: '',
31
+ controllers_path: '',
34
32
  services: [],
35
33
  logger: nil,
36
34
  grpc_logger: nil,
37
35
  error_metadata_key: :'error-internal-bin',
38
36
  error_serializer: nil,
39
- authorization_metadata_key: 'authorization',
40
37
  append_server_errors_to_trailing_metadata: true,
41
- use_default_hooks: true,
38
+ use_default_interceptors: true,
42
39
  backtrace_on_error: false,
43
40
  use_exception_message: true,
44
41
  internal_error_message: 'Internal Server Error'
@@ -85,27 +82,21 @@ module Gruf
85
82
  VALID_CONFIG_KEYS.each do |k, v|
86
83
  send((k.to_s + '='), v)
87
84
  end
85
+ self.interceptors = Gruf::Interceptors::Registry.new
86
+ self.root_path = Rails.root.to_s.chomp('/') if defined?(Rails)
88
87
  if defined?(Rails) && Rails.logger
89
- self.root_path = Rails.root
90
88
  self.logger = Rails.logger
91
89
  else
92
90
  require 'logger'
93
91
  self.logger = ::Logger.new(STDOUT)
94
92
  end
95
93
  self.grpc_logger = logger if grpc_logger.nil?
96
- self.ssl_crt_file = "#{root_path}/config/ssl/#{environment}.crt"
97
- self.ssl_key_file = "#{root_path}/config/ssl/#{environment}.key"
98
- self.servers_path = "#{root_path}/app/rpc"
99
- self.authentication_options = {
100
- credentials: [{
101
- username: 'grpc',
102
- password: 'magic'
103
- }]
104
- }
105
- if use_default_hooks
106
- Gruf::Hooks::Registry.add(:ar_connection_reset, Gruf::Hooks::ActiveRecord::ConnectionReset)
107
- Gruf::Instrumentation::Registry.add(:output_metadata_timer, Gruf::Instrumentation::OutputMetadataTimer)
108
- Gruf::Instrumentation::Registry.add(:request_logging, Gruf::Instrumentation::RequestLogging::Hook)
94
+ self.ssl_crt_file = "#{root_path}config/ssl/#{environment}.crt"
95
+ self.ssl_key_file = "#{root_path}config/ssl/#{environment}.key"
96
+ self.controllers_path = root_path.to_s.empty? ? 'app/rpc' : "#{root_path}/app/rpc"
97
+ if use_default_interceptors
98
+ interceptors.use(Gruf::Interceptors::ActiveRecord::ConnectionReset)
99
+ interceptors.use(Gruf::Interceptors::Instrumentation::OutputMetadataTimer)
109
100
  end
110
101
  options
111
102
  end