gruf 2.9.1 → 2.15.1

Sign up to get free protection for your applications and to get access to all the features.
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