gruf 2.13.1 → 2.17.0

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.
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ require 'grpc/health/v1/health_services_pb'
19
+
20
+ module Gruf
21
+ module Controllers
22
+ ##
23
+ # Dynamic standard grpc health check controller. Can be used as-is, or can use ::Gruf.health_check_hook to
24
+ # provide custom responses.
25
+ #
26
+ class HealthController < Gruf::Controllers::Base
27
+ bind ::Grpc::Health::V1::Health::Service
28
+
29
+ def check
30
+ health_proc = ::Gruf.health_check_hook
31
+ return health_proc.call(request, error) if !health_proc.nil? && health_proc.respond_to?(:call)
32
+
33
+ ::Grpc::Health::V1::HealthCheckResponse.new(
34
+ status: ::Grpc::Health::V1::HealthCheckResponse::ServingStatus::SERVING
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -36,6 +36,11 @@ module Gruf
36
36
  # @!attribute [r] service
37
37
  # @return [Class] The GRPC service class for this request
38
38
  attr_reader :service
39
+ # @!attribute [r] context
40
+ # @return [::ActiveSupport::HashWithIndifferentAccess] An arbitrary hash of key/value entries that are
41
+ # accessible for interceptors, that can be used to shared information between interceptors and pass down into
42
+ # the controller.
43
+ attr_reader :context
39
44
 
40
45
  delegate :metadata, to: :active_call
41
46
  delegate :messages, :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :type
@@ -72,6 +77,7 @@ module Gruf
72
77
  @message = message
73
78
  @rpc_desc = rpc_desc
74
79
  @type = Type.new(rpc_desc)
80
+ @context = ::ActiveSupport::HashWithIndifferentAccess.new
75
81
  end
76
82
 
77
83
  ##
@@ -26,92 +26,84 @@ module Gruf
26
26
  #
27
27
  class BoundDesc < SimpleDelegator; end
28
28
 
29
- ##
30
- # Initialize a service binder instance with the given service
31
- #
32
- # @param [GRPC::GenericService] service The gRPC service stub to bind
33
- #
34
- def initialize(service)
35
- @service = service
36
- end
37
-
38
- ##
39
- # Bind all methods on the service to the passed controller
40
- #
41
- # @param [Class<Gruf::Controllers::Base>] controller
42
- #
43
- def bind!(controller)
44
- rpc_methods.each { |name, desc| bind_method(controller, name, desc) }
45
- end
46
-
47
- private
48
-
49
- ##
50
- # Bind the grpc methods to the service, allowing for server interception and execution control
51
- #
52
- # @param [Gruf::Controllers::Base] controller
53
- # @param [Symbol] method_name
54
- # @param [BoundDesc] desc
55
- #
56
- def bind_method(controller, method_name, desc)
57
- method_key = method_name.to_s.underscore.to_sym
58
- service_ref = @service
29
+ class << self
30
+ ##
31
+ # Bind all methods on the service to the passed controller
32
+ #
33
+ # @param [Class<Gruf::Controllers::Base>] controller
34
+ #
35
+ def bind!(service:, controller:)
36
+ rpc_methods = service.rpc_descs.map { |rd| BoundDesc.new(rd) }
37
+ rpc_methods.each { |name, desc| bind_method(service, controller, name, desc) }
38
+ end
59
39
 
60
- @service.class_eval do
61
- if desc.request_response?
62
- define_method(method_key) do |message, active_call|
63
- c = controller.new(
64
- method_key: method_key,
65
- service: service_ref,
66
- message: message,
67
- active_call: active_call,
68
- rpc_desc: desc
69
- )
70
- c.call(method_key)
71
- end
72
- elsif desc.client_streamer?
73
- define_method(method_key) do |active_call|
74
- c = controller.new(
75
- method_key: method_key,
76
- service: service_ref,
77
- message: proc { |&block| active_call.each_remote_read(&block) },
78
- active_call: active_call,
79
- rpc_desc: desc
80
- )
81
- c.call(method_key)
82
- end
83
- elsif desc.server_streamer?
84
- define_method(method_key) do |message, active_call, &block|
85
- c = controller.new(
86
- method_key: method_key,
87
- service: service_ref,
88
- message: message,
89
- active_call: active_call,
90
- rpc_desc: desc
91
- )
92
- c.call(method_key, &block)
93
- end
94
- else # bidi
95
- define_method(method_key) do |messages, active_call, &block|
96
- c = controller.new(
97
- method_key: method_key,
98
- service: service_ref,
99
- message: messages,
100
- active_call: active_call,
101
- rpc_desc: desc
102
- )
103
- c.call(method_key, &block)
40
+ ##
41
+ # Bind the grpc methods to the service, allowing for server interception and execution control
42
+ #
43
+ # @param [Gruf::Controllers::Base] controller
44
+ # @param [Symbol] method_name
45
+ # @param [BoundDesc] desc
46
+ #
47
+ def bind_method(service_ref, controller, method_name, desc)
48
+ method_key = method_name.to_s.underscore.to_sym
49
+ controller_name = controller.name
50
+ service_ref.class_eval do
51
+ if desc.request_response?
52
+ define_method(method_key) do |message, active_call|
53
+ Gruf::Autoloaders.controllers.with_fresh_controller(controller_name) do |fresh_controller|
54
+ c = fresh_controller.new(
55
+ method_key: method_key,
56
+ service: service_ref,
57
+ message: message,
58
+ active_call: active_call,
59
+ rpc_desc: desc
60
+ )
61
+ c.call(method_key)
62
+ end
63
+ end
64
+ elsif desc.client_streamer?
65
+ define_method(method_key) do |active_call|
66
+ Gruf::Autoloaders.controllers.with_fresh_controller(controller_name) do |fresh_controller|
67
+ c = fresh_controller.new(
68
+ method_key: method_key,
69
+ service: service_ref,
70
+ message: proc { |&block| active_call.each_remote_read(&block) },
71
+ active_call: active_call,
72
+ rpc_desc: desc
73
+ )
74
+ c.call(method_key)
75
+ end
76
+ end
77
+ elsif desc.server_streamer?
78
+ define_method(method_key) do |message, active_call, &block|
79
+ Gruf::Autoloaders.controllers.with_fresh_controller(controller_name) do |fresh_controller|
80
+ c = fresh_controller.new(
81
+ method_key: method_key,
82
+ service: service_ref,
83
+ message: message,
84
+ active_call: active_call,
85
+ rpc_desc: desc
86
+ )
87
+ c.call(method_key, &block)
88
+ end
89
+ end
90
+ else # bidi
91
+ define_method(method_key) do |messages, active_call, &block|
92
+ Gruf::Autoloaders.controllers.with_fresh_controller(controller_name) do |fresh_controller|
93
+ c = fresh_controller.new(
94
+ method_key: method_key,
95
+ service: service_ref,
96
+ message: messages,
97
+ active_call: active_call,
98
+ rpc_desc: desc
99
+ )
100
+ c.call(method_key, &block)
101
+ end
102
+ end
104
103
  end
105
104
  end
106
105
  end
107
106
  end
108
-
109
- ##
110
- # @return Array<Gruf::Controllers::ServiceBinder::BoundDesc>
111
- #
112
- def rpc_methods
113
- @service.rpc_descs.map { |rd| BoundDesc.new(rd) }
114
- end
115
107
  end
116
108
  end
117
109
  end
data/lib/gruf/error.rb CHANGED
@@ -15,10 +15,6 @@
15
15
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
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
- require_relative 'errors/field'
19
- require_relative 'errors/debug_info'
20
- require_relative 'serializers/errors/base'
21
- require_relative 'serializers/errors/json'
22
18
 
23
19
  module Gruf
24
20
  ##
@@ -16,20 +16,6 @@
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
- ##
20
- # Handles internal gruf logging requests
21
- #
22
- module Logger
23
- ##
24
- # Return the current Gruf logger
25
- #
26
- # @return [Logger]
27
- #
28
- def logger
29
- Gruf.logger
30
- end
31
- end
32
-
33
19
  ##
34
20
  # Handles grpc internal logging requests
35
21
  #
@@ -1,9 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
3
18
  module Gruf
4
19
  module Integrations
5
20
  module Rails
21
+ ##
22
+ # Rails integration for Gruf, that currently only manages code autoloading in a Rails context
23
+ #
6
24
  class Railtie < ::Rails::Railtie
25
+ initializer 'gruf.initializer' do |app|
26
+ config.before_configuration do
27
+ # Remove autoloading of the controllers path from Rails' zeitwerk, so that we ensure Gruf's zeitwerk
28
+ # properly manages them itself. This allows us to manage code reloading and logging in Gruf specifically
29
+ app.config.eager_load_paths -= [::Gruf.controllers_path] if app.config.respond_to?(:eager_load_paths)
30
+ if ::Rails.respond_to?(:autoloaders) # if we're on a late enough version of rails
31
+ ::Rails.autoloaders.each do |autoloader|
32
+ autoloader.ignore(Gruf.controllers_path)
33
+ end
34
+ end
35
+ end
36
+ end
7
37
  end
8
38
  end
9
39
  end
@@ -27,11 +27,13 @@ module Gruf
27
27
  # connection pool, we need to ensure that this is done to properly
28
28
  #
29
29
  def call
30
- ::ActiveRecord::Base.establish_connection if enabled? && !::ActiveRecord::Base.connection.active?
30
+ if enabled?
31
+ target_classes.each { |klass| klass.establish_connection unless klass.connection.active? }
32
+ end
31
33
 
32
34
  yield
33
35
  ensure
34
- ::ActiveRecord::Base.clear_active_connections! if enabled?
36
+ target_classes.each(&:clear_active_connections!) if enabled?
35
37
  end
36
38
 
37
39
  private
@@ -42,6 +44,13 @@ module Gruf
42
44
  def enabled?
43
45
  defined?(::ActiveRecord::Base)
44
46
  end
47
+
48
+ ##
49
+ # @return [Array<Class>] The list of ActiveRecord classes to reset
50
+ #
51
+ def target_classes
52
+ options[:target_classes] || [::ActiveRecord::Base]
53
+ end
45
54
  end
46
55
  end
47
56
  end
@@ -44,13 +44,3 @@ module Gruf
44
44
  end
45
45
  end
46
46
  end
47
-
48
- require_relative 'client_interceptor'
49
- require_relative 'server_interceptor'
50
- require_relative 'context'
51
- require_relative 'timer'
52
- require_relative 'active_record/connection_reset'
53
- require_relative 'authentication/basic'
54
- require_relative 'instrumentation/statsd'
55
- require_relative 'instrumentation/output_metadata_timer'
56
- require_relative 'instrumentation/request_logging/interceptor'
@@ -16,9 +16,6 @@
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
  require 'socket'
19
- require_relative 'formatters/base'
20
- require_relative 'formatters/logstash'
21
- require_relative 'formatters/plain'
22
19
 
23
20
  module Gruf
24
21
  module Interceptors
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ # Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ #
18
+ module Gruf
19
+ ##
20
+ # Handles internal gruf logging requests
21
+ #
22
+ module Logger
23
+ ##
24
+ # Return the current Gruf logger
25
+ #
26
+ # @return [Logger]
27
+ #
28
+ def logger
29
+ Gruf.logger
30
+ end
31
+ end
32
+ end
data/lib/gruf/server.rb CHANGED
@@ -43,39 +43,45 @@ module Gruf
43
43
  @options = opts || {}
44
44
  @interceptors = opts.fetch(:interceptor_registry, Gruf.interceptors)
45
45
  @interceptors = Gruf::Interceptors::Registry.new unless @interceptors.is_a?(Gruf::Interceptors::Registry)
46
- @services = []
46
+ @services = nil
47
47
  @started = false
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 ||= 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
56
+ server_mutex do
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
+ # 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) }
83
+ server
84
+ end
79
85
  end
80
86
  end
81
87
 
@@ -87,7 +93,7 @@ module Gruf
87
93
  update_proc_title(:starting)
88
94
 
89
95
  server_thread = Thread.new do
90
- logger.info { "Starting gruf server at #{@hostname}..." }
96
+ logger.info { "[gruf] Starting gruf server at #{@hostname}..." }
91
97
  server.run_till_terminated_or_interrupted(KILL_SIGNALS)
92
98
  end
93
99
  @started = true
@@ -96,7 +102,7 @@ module Gruf
96
102
  @started = false
97
103
 
98
104
  update_proc_title(:stopped)
99
- logger.info { 'Goodbye!' }
105
+ logger.info { '[gruf] Goodbye!' }
100
106
  end
101
107
  # :nocov:
102
108
 
@@ -109,7 +115,7 @@ module Gruf
109
115
  def add_service(klass)
110
116
  raise ServerAlreadyStartedError if @started
111
117
 
112
- @services << klass unless @services.include?(klass)
118
+ @services << klass unless services.include?(klass)
113
119
  end
114
120
 
115
121
  ##
@@ -183,31 +189,11 @@ module Gruf
183
189
  private
184
190
 
185
191
  ##
186
- # Setup server
187
- #
188
- # :nocov:
189
- def setup
190
- load_controllers
191
- end
192
- # :nocov:
193
-
194
- ##
195
- # Auto-load all gRPC handlers
192
+ # @return [Array<Class>]
196
193
  #
197
- # :nocov:
198
- def load_controllers
199
- return unless File.directory?(controllers_path)
200
-
201
- path = File.realpath(controllers_path)
202
- $LOAD_PATH.unshift(path)
203
- Dir["#{path}/**/*.rb"].each do |f|
204
- next if f.include?('_pb') # exclude if people include proto generated files in app/rpc
205
-
206
- logger.info "- Loading gRPC service file: #{f}"
207
- load File.realpath(f)
208
- end
194
+ def services
195
+ @services ||= (::Gruf.services || (options.fetch(:services, nil) || []))
209
196
  end
210
- # :nocov:
211
197
 
212
198
  ##
213
199
  # @param [String]
@@ -242,5 +228,17 @@ module Gruf
242
228
  Process.setproctitle("gruf #{Gruf::VERSION} -- #{state}")
243
229
  end
244
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
245
243
  end
246
244
  end
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.13.1'
19
+ VERSION = '2.17.0'
20
20
  end
data/lib/gruf.rb CHANGED
@@ -17,29 +17,21 @@
17
17
  #
18
18
  require 'grpc'
19
19
  require 'active_support/core_ext/module/delegation'
20
+ require 'active_support/hash_with_indifferent_access'
20
21
  require 'active_support/concern'
21
22
  require 'active_support/inflector'
22
23
  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'
24
+
25
+ # use Zeitwerk to lazily autoload all the files in the lib directory
26
+ require 'zeitwerk'
27
+ loader = ::Zeitwerk::Loader.new
28
+ loader.tag = File.basename(__FILE__, '.rb')
29
+ loader.inflector = ::Zeitwerk::GemInflector.new(__FILE__)
30
+ loader.ignore("#{__dir__}/gruf/integrations/rails/railtie.rb")
31
+ loader.ignore("#{__dir__}/gruf/controllers/health_controller.rb")
32
+ loader.push_dir(__dir__)
33
+ loader.setup
34
+
43
35
  require_relative 'gruf/integrations/rails/railtie' if defined?(::Rails)
44
36
 
45
37
  ##
@@ -47,4 +39,10 @@ require_relative 'gruf/integrations/rails/railtie' if defined?(::Rails)
47
39
  #
48
40
  module Gruf
49
41
  extend Configuration
42
+
43
+ class << self
44
+ def autoloaders
45
+ Autoloaders
46
+ end
47
+ end
50
48
  end