gruf 2.9.1 → 2.15.1

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.
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
- # @return [Integer] The port the server is bound to
30
+ # @!attribute [r] port
31
+ # @return [Integer] The port the server is bound to
29
32
  attr_reader :port
30
- # @return [Hash] Hash of options passed into the server
33
+ # @!attribute [r] options
34
+ # @return [Hash] Hash of options passed into the server
31
35
  attr_reader :options
32
36
 
33
37
  ##
@@ -39,22 +43,17 @@ module Gruf
39
43
  @options = opts || {}
40
44
  @interceptors = opts.fetch(:interceptor_registry, Gruf.interceptors)
41
45
  @interceptors = Gruf::Interceptors::Registry.new unless @interceptors.is_a?(Gruf::Interceptors::Registry)
42
- @services = []
46
+ @services = nil
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
- setup
51
50
  end
52
51
 
53
52
  ##
54
53
  # @return [GRPC::RpcServer] The GRPC server running
55
54
  #
56
55
  def server
57
- @server_mu.synchronize do
56
+ server_mutex do
58
57
  @server ||= begin
59
58
  # For backward compatibility, we allow these options to be passed directly
60
59
  # in the Gruf::Server options, or via Gruf.rpc_server_options.
@@ -75,7 +74,12 @@ module Gruf
75
74
  end
76
75
 
77
76
  @port = server.add_http2_port(@hostname, ssl_credentials)
78
- @services.each { |s| server.handle(s) }
77
+ # do not reference `services` any earlier than this method, as it allows autoloading to take effect
78
+ # and load services into `Gruf.services` as late as possible, which gives us flexibility with different
79
+ # execution paths (such as vanilla ruby, grape, multiple Rails versions, etc). The autoloaders are
80
+ # initially loaded in `Gruf::Cli::Executor` _directly_ before the gRPC services are loaded into the gRPC
81
+ # server, to allow for loading services as late as possible in the execution chain.
82
+ services.each { |s| server.handle(s) }
79
83
  server
80
84
  end
81
85
  end
@@ -89,29 +93,16 @@ module Gruf
89
93
  update_proc_title(:starting)
90
94
 
91
95
  server_thread = Thread.new do
92
- logger.info { "Starting gruf server at #{@hostname}..." }
93
- server.run
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
96
+ logger.info { "[gruf] Starting gruf server at #{@hostname}..." }
97
+ server.run_till_terminated_or_interrupted(KILL_SIGNALS)
104
98
  end
105
-
106
- server.wait_till_running
107
99
  @started = true
108
100
  update_proc_title(:serving)
109
- stop_server_thread.join
110
101
  server_thread.join
111
102
  @started = false
112
103
 
113
104
  update_proc_title(:stopped)
114
- logger.info { 'Goodbye!' }
105
+ logger.info { '[gruf] Goodbye!' }
115
106
  end
116
107
  # :nocov:
117
108
 
@@ -124,7 +115,7 @@ module Gruf
124
115
  def add_service(klass)
125
116
  raise ServerAlreadyStartedError if @started
126
117
 
127
- @services << klass unless @services.include?(klass)
118
+ @services << klass unless services.include?(klass)
128
119
  end
129
120
 
130
121
  ##
@@ -198,49 +189,11 @@ module Gruf
198
189
  private
199
190
 
200
191
  ##
201
- # Setup server
202
- #
203
- # :nocov:
204
- def setup
205
- setup_signal_handlers
206
- load_controllers
207
- end
208
- # :nocov:
209
-
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
- ##
228
- # Auto-load all gRPC handlers
192
+ # @return [Array<Class>]
229
193
  #
230
- # :nocov:
231
- def load_controllers
232
- return unless File.directory?(controllers_path)
233
-
234
- path = File.realpath(controllers_path)
235
- $LOAD_PATH.unshift(path)
236
- Dir["#{path}/**/*.rb"].each do |f|
237
- next if f.include?('_pb') # exclude if people include proto generated files in app/rpc
238
-
239
- logger.info "- Loading gRPC service file: #{f}"
240
- load File.realpath(f)
241
- end
194
+ def services
195
+ @services ||= (::Gruf.services || (options.fetch(:services, nil) || []))
242
196
  end
243
- # :nocov:
244
197
 
245
198
  ##
246
199
  # @param [String]
@@ -275,5 +228,17 @@ module Gruf
275
228
  Process.setproctitle("gruf #{Gruf::VERSION} -- #{state}")
276
229
  end
277
230
  # :nocov:
231
+ #
232
+
233
+ ##
234
+ # Handle thread-safe access to the server
235
+ #
236
+ def server_mutex(&block)
237
+ @server_mutex ||= begin
238
+ require 'monitor'
239
+ Monitor.new
240
+ end
241
+ @server_mutex.synchronize(&block)
242
+ end
278
243
  end
279
244
  end
@@ -23,6 +23,8 @@ module Gruf
23
23
  # to mitigate thundering herds.
24
24
  #
25
25
  class SynchronizedClient < Gruf::Client
26
+ # @!attribute [r] unsynchronized_methods
27
+ # @return [Array]
26
28
  attr_reader :unsynchronized_methods
27
29
 
28
30
  ##
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
- attr_reader :result,
37
- :time
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
@@ -16,5 +16,5 @@
16
16
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
17
  #
18
18
  module Gruf
19
- VERSION = '2.9.1'
19
+ VERSION = '2.15.1'
20
20
  end
data/lib/gruf.rb CHANGED
@@ -20,31 +20,27 @@ require 'active_support/core_ext/module/delegation'
20
20
  require 'active_support/concern'
21
21
  require 'active_support/inflector'
22
22
  require 'base64'
23
- require_relative 'gruf/version'
24
- require_relative 'gruf/logging'
25
- require_relative 'gruf/loggable'
26
- require_relative 'gruf/configuration'
27
- require_relative 'gruf/errors/helpers'
28
- require_relative 'gruf/cli/executor'
29
- require_relative 'gruf/controllers/base'
30
- require_relative 'gruf/outbound/request_context'
31
- require_relative 'gruf/interceptors/registry'
32
- require_relative 'gruf/interceptors/base'
33
- require_relative 'gruf/hooks/registry'
34
- require_relative 'gruf/hooks/executor'
35
- require_relative 'gruf/hooks/base'
36
- require_relative 'gruf/timer'
37
- require_relative 'gruf/response'
38
- require_relative 'gruf/error'
39
- require_relative 'gruf/client'
40
- require_relative 'gruf/synchronized_client'
41
- require_relative 'gruf/instrumentable_grpc_server'
42
- require_relative 'gruf/server'
43
- require_relative 'gruf/integrations/rails/railtie' if defined?(Rails)
23
+
24
+ # use Zeitwerk to lazily autoload all the files in the lib directory
25
+ require 'zeitwerk'
26
+ loader = ::Zeitwerk::Loader.new
27
+ loader.tag = File.basename(__FILE__, '.rb')
28
+ loader.inflector = ::Zeitwerk::GemInflector.new(__FILE__)
29
+ loader.ignore("#{__dir__}/gruf/integrations/rails/railtie.rb")
30
+ loader.push_dir(__dir__)
31
+ loader.setup
32
+
33
+ require_relative 'gruf/integrations/rails/railtie' if defined?(::Rails)
44
34
 
45
35
  ##
46
36
  # Initializes configuration of gruf core module
47
37
  #
48
38
  module Gruf
49
39
  extend Configuration
40
+
41
+ class << self
42
+ def autoloaders
43
+ Autoloaders
44
+ end
45
+ end
50
46
  end
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.9.1
4
+ version: 2.15.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: 2021-03-15 00:00:00.000000000 Z
11
+ date: 2022-07-08 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,30 +280,44 @@ 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'
307
+ - !ruby/object:Gem::Dependency
308
+ name: zeitwerk
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '2'
314
+ type: :runtime
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - ">="
319
+ - !ruby/object:Gem::Version
320
+ version: '2'
321
321
  description: gRPC Ruby Framework for building complex gRPC applications at scale
322
322
  email:
323
323
  - splittingred@gmail.com
@@ -332,11 +332,14 @@ files:
332
332
  - bin/gruf
333
333
  - gruf.gemspec
334
334
  - lib/gruf.rb
335
+ - lib/gruf/autoloaders.rb
335
336
  - lib/gruf/cli/executor.rb
336
337
  - lib/gruf/client.rb
337
338
  - lib/gruf/client/error.rb
338
339
  - lib/gruf/client/error_factory.rb
340
+ - lib/gruf/client/errors.rb
339
341
  - lib/gruf/configuration.rb
342
+ - lib/gruf/controllers/autoloader.rb
340
343
  - lib/gruf/controllers/base.rb
341
344
  - lib/gruf/controllers/request.rb
342
345
  - lib/gruf/controllers/service_binder.rb
@@ -344,6 +347,7 @@ files:
344
347
  - lib/gruf/errors/debug_info.rb
345
348
  - lib/gruf/errors/field.rb
346
349
  - lib/gruf/errors/helpers.rb
350
+ - lib/gruf/grpc_logger.rb
347
351
  - lib/gruf/hooks/base.rb
348
352
  - lib/gruf/hooks/executor.rb
349
353
  - lib/gruf/hooks/registry.rb
@@ -364,7 +368,7 @@ files:
364
368
  - lib/gruf/interceptors/server_interceptor.rb
365
369
  - lib/gruf/interceptors/timer.rb
366
370
  - lib/gruf/loggable.rb
367
- - lib/gruf/logging.rb
371
+ - lib/gruf/logger.rb
368
372
  - lib/gruf/outbound/request_context.rb
369
373
  - lib/gruf/response.rb
370
374
  - lib/gruf/serializers/errors/base.rb
@@ -376,7 +380,13 @@ files:
376
380
  homepage: https://github.com/bigcommerce/gruf
377
381
  licenses:
378
382
  - MIT
379
- metadata: {}
383
+ metadata:
384
+ bug_tracker_uri: https://github.com/bigcommerce/gruf/issues
385
+ changelog_uri: https://github.com/bigcommerce/gruf/CHANGELOG.md
386
+ homepage_uri: https://github.com/bigcommerce/gruf
387
+ rubygems_mfa_required: 'true'
388
+ source_code_uri: https://github.com/bigcommerce/gruf
389
+ wiki_uri: https://github.com/bigcommerce/gruf/wiki
380
390
  post_install_message:
381
391
  rdoc_options: []
382
392
  require_paths:
@@ -385,17 +395,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
385
395
  requirements:
386
396
  - - ">="
387
397
  - !ruby/object:Gem::Version
388
- version: '2.4'
398
+ version: '2.6'
389
399
  - - "<"
390
400
  - !ruby/object:Gem::Version
391
- version: '3.1'
401
+ version: '3.2'
392
402
  required_rubygems_version: !ruby/object:Gem::Requirement
393
403
  requirements:
394
404
  - - ">="
395
405
  - !ruby/object:Gem::Version
396
406
  version: '0'
397
407
  requirements: []
398
- rubygems_version: 3.0.9
408
+ rubygems_version: 3.3.12
399
409
  signing_key:
400
410
  specification_version: 4
401
411
  summary: gRPC Ruby Framework