gruf 2.16.2 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0508561578b2ebd6490bebfeeee8f4442d4bcec1d1cb877dc0005933564fc33
4
- data.tar.gz: b4130a47d10681a4876046aa782640091799d99f433cc5f6ae55f6dce1f60ecf
3
+ metadata.gz: 3de94291c905860137fbeb2be431f470af5929eddd3df869b602944dbe3253ea
4
+ data.tar.gz: 282cd45242df875e8c664a9434bb7364592a5062e4d3d4980972d9a314931996
5
5
  SHA512:
6
- metadata.gz: 1a9e198be4481b4e56c3e57fb7d76be2ce97e6cbe30368fadc990a505d1864c98f1e0d25f02c8209a0dafd89021537b15f6f12a83323ec3c8a7ff114c7c8094b
7
- data.tar.gz: 5fc8489af23aa0e387aa84dc4104e7812aa0a767ddb32e6bf83f331442b79073f57c5ef97b2326ff9ec64cebf018d76589ce5f964bf67a69e758dd0780508423
6
+ metadata.gz: d06b793680ecc5064ec5b4978b83a1a18903f9647b733b3e19ff32979044ab129130019780fafb7f09703f1d7e16ecd5983bf5fa0bd08b1906b4af6597f4c832
7
+ data.tar.gz: 7e37790c465cbbf80e1d02d1e71fc9a5e8276fb21d6fb894ae19f6eef663910e4df956293dc218b8de91d940d2586e65248f4f6aababd4d661fb4fdad10d37ce
data/CHANGELOG.md CHANGED
@@ -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.18.0
6
+
7
+ * Add `GRUF_USE_DEFAULT_INTERCEPTORS` ENV to dynamically enable/disable default interceptors
8
+ * Allow passing of request object directly into `call`
9
+
10
+ ### 2.17.0
11
+
12
+ * [#179] Add Ruby 3.2 support
13
+ * [#178] Introduce read-write lock for code reloading; cover controller class resolution with code reloading.
14
+ * [#180] Support multiple databases connection reset in `Gruf::Interceptors::ActiveRecord::ConnectionReset`.
15
+
5
16
  ### 2.16.2
6
17
 
7
18
  * [#175] Fix code reload thread-safety. Calls to `Zeitwerk::Loader#setup` are now made in a thread-safe manner.
data/README.md CHANGED
@@ -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.6-3.1.
20
+ gruf currently has active support for gRPC 1.10.x+. gruf is compatible and tested with Ruby 2.7-3.2.
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
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.executables << 'gruf'
33
33
  spec.require_paths = ['lib']
34
34
 
35
- spec.required_ruby_version = '>= 2.7', '< 3.2'
35
+ spec.required_ruby_version = '>= 2.7', '< 3.3'
36
36
 
37
37
  spec.metadata = {
38
38
  'bug_tracker_uri' => 'https://github.com/bigcommerce/gruf/issues',
@@ -43,20 +43,6 @@ Gem::Specification.new do |spec|
43
43
  'wiki_uri' => 'https://github.com/bigcommerce/gruf/wiki'
44
44
  }
45
45
 
46
- spec.add_development_dependency 'bundler-audit', '>= 0.6'
47
- spec.add_development_dependency 'factory_bot', '>= 6.1'
48
- spec.add_development_dependency 'ffaker', '>= 2.15'
49
- spec.add_development_dependency 'pry', '~> 0.12'
50
- spec.add_development_dependency 'pry-byebug', '>= 3.9'
51
- spec.add_development_dependency 'rake', '>= 10.0'
52
- spec.add_development_dependency 'rspec', '>= 3.8'
53
- spec.add_development_dependency 'rspec_junit_formatter', '>= 0.4'
54
- spec.add_development_dependency 'rubocop', '>= 1.0'
55
- spec.add_development_dependency 'rubocop-performance', '>= 0.0.1'
56
- spec.add_development_dependency 'rubocop-rspec', '>= 2.0'
57
- spec.add_development_dependency 'rubocop-thread_safety', '>= 0.3'
58
- spec.add_development_dependency 'simplecov', '>= 0.16'
59
-
60
46
  spec.add_runtime_dependency 'activesupport', '> 4'
61
47
  spec.add_runtime_dependency 'concurrent-ruby', '> 1'
62
48
  spec.add_runtime_dependency 'e2mmap', '>= 0.1'
data/lib/gruf/client.rb CHANGED
@@ -81,7 +81,11 @@ module Gruf
81
81
  #
82
82
  def call(request_method, params = {}, metadata = {}, opts = {}, &block)
83
83
  request_method = request_method.to_sym
84
- req = streaming_request?(request_method) ? params : request_object(request_method, params)
84
+ req = if params.respond_to?(:to_proto) || streaming_request?(request_method)
85
+ params
86
+ else
87
+ request_object(request_method, params)
88
+ end
85
89
  md = build_metadata(metadata)
86
90
  call_sig = call_signature(request_method)
87
91
 
@@ -186,6 +186,8 @@ module Gruf
186
186
  connect_md_proc: nil,
187
187
  server_args: {}
188
188
  }
189
+ self.use_default_interceptors = ::ENV.fetch('GRUF_USE_DEFAULT_INTERCEPTORS', 1).to_i.positive?
190
+
189
191
  if use_default_interceptors
190
192
  interceptors.use(::Gruf::Interceptors::ActiveRecord::ConnectionReset)
191
193
  interceptors.use(::Gruf::Interceptors::Instrumentation::OutputMetadataTimer)
@@ -15,6 +15,8 @@
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 'concurrent/atomic/read_write_lock'
19
+
18
20
  module Gruf
19
21
  module Controllers
20
22
  ##
@@ -47,10 +49,19 @@ module Gruf
47
49
  # Reload all files managed by the autoloader, if reloading is enabled
48
50
  #
49
51
  def reload
50
- if @reloading_enabled
51
- reload_mutex do
52
- @loader.reload
53
- end
52
+ return unless @reloading_enabled
53
+
54
+ reload_lock.with_write_lock do
55
+ @loader.reload
56
+ end
57
+ end
58
+
59
+ def with_fresh_controller(controller_name)
60
+ return yield(controller_name.constantize) unless @reloading_enabled
61
+
62
+ ::Gruf::Autoloaders.reload
63
+ reload_lock.with_read_lock do
64
+ yield(controller_name.constantize)
54
65
  end
55
66
  end
56
67
 
@@ -77,12 +88,8 @@ module Gruf
77
88
  ##
78
89
  # Handle thread-safe access to the loader
79
90
  #
80
- def reload_mutex(&block)
81
- @reload_mutex ||= begin
82
- require 'monitor'
83
- Monitor.new
84
- end
85
- @reload_mutex.synchronize(&block)
91
+ def reload_lock
92
+ @reload_lock ||= Concurrent::ReadWriteLock.new
86
93
  end
87
94
  end
88
95
  end
@@ -90,7 +90,6 @@ module Gruf
90
90
  # @param [block] &block The passed block for executing the method
91
91
  #
92
92
  def call(method_key, &block)
93
- ::Gruf.autoloaders.reload if ::Gruf.development?
94
93
  Interceptors::Context.new(@interceptors).intercept! do
95
94
  process_action(method_key, &block)
96
95
  end
@@ -46,54 +46,59 @@ module Gruf
46
46
  #
47
47
  def bind_method(service_ref, controller, method_name, desc)
48
48
  method_key = method_name.to_s.underscore.to_sym
49
+ controller_name = controller.name
49
50
  service_ref.class_eval do
50
51
  if desc.request_response?
51
52
  define_method(method_key) do |message, active_call|
52
- controller = controller.name.constantize
53
- c = controller.new(
54
- method_key: method_key,
55
- service: service_ref,
56
- message: message,
57
- active_call: active_call,
58
- rpc_desc: desc
59
- )
60
- c.call(method_key)
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
61
63
  end
62
64
  elsif desc.client_streamer?
63
65
  define_method(method_key) do |active_call|
64
- controller = controller.name.constantize
65
- c = controller.new(
66
- method_key: method_key,
67
- service: service_ref,
68
- message: proc { |&block| active_call.each_remote_read(&block) },
69
- active_call: active_call,
70
- rpc_desc: desc
71
- )
72
- c.call(method_key)
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
73
76
  end
74
77
  elsif desc.server_streamer?
75
78
  define_method(method_key) do |message, active_call, &block|
76
- controller = controller.name.constantize
77
- c = controller.new(
78
- method_key: method_key,
79
- service: service_ref,
80
- message: message,
81
- active_call: active_call,
82
- rpc_desc: desc
83
- )
84
- c.call(method_key, &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
85
89
  end
86
90
  else # bidi
87
91
  define_method(method_key) do |messages, active_call, &block|
88
- controller = controller.name.constantize
89
- c = controller.new(
90
- method_key: method_key,
91
- service: service_ref,
92
- message: messages,
93
- active_call: active_call,
94
- rpc_desc: desc
95
- )
96
- c.call(method_key, &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
97
102
  end
98
103
  end
99
104
  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
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.16.2'
19
+ VERSION = '2.18.0'
20
20
  end
metadata CHANGED
@@ -1,197 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gruf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.2
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shaun McCormick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-21 00:00:00.000000000 Z
11
+ date: 2023-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler-audit
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0.6'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0.6'
27
- - !ruby/object:Gem::Dependency
28
- name: factory_bot
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '6.1'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '6.1'
41
- - !ruby/object:Gem::Dependency
42
- name: ffaker
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '2.15'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '2.15'
55
- - !ruby/object:Gem::Dependency
56
- name: pry
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.12'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.12'
69
- - !ruby/object:Gem::Dependency
70
- name: pry-byebug
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '3.9'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '3.9'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '10.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '10.0'
97
- - !ruby/object:Gem::Dependency
98
- name: rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '3.8'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '3.8'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec_junit_formatter
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0.4'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0.4'
125
- - !ruby/object:Gem::Dependency
126
- name: rubocop
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '1.0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '1.0'
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop-performance
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: 0.0.1
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: 0.0.1
153
- - !ruby/object:Gem::Dependency
154
- name: rubocop-rspec
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '2.0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '2.0'
167
- - !ruby/object:Gem::Dependency
168
- name: rubocop-thread_safety
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0.3'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0.3'
181
- - !ruby/object:Gem::Dependency
182
- name: simplecov
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0.16'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0.16'
195
13
  - !ruby/object:Gem::Dependency
196
14
  name: activesupport
197
15
  requirement: !ruby/object:Gem::Requirement
@@ -399,14 +217,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
399
217
  version: '2.7'
400
218
  - - "<"
401
219
  - !ruby/object:Gem::Version
402
- version: '3.2'
220
+ version: '3.3'
403
221
  required_rubygems_version: !ruby/object:Gem::Requirement
404
222
  requirements:
405
223
  - - ">="
406
224
  - !ruby/object:Gem::Version
407
225
  version: '0'
408
226
  requirements: []
409
- rubygems_version: 3.3.3
227
+ rubygems_version: 3.4.10
410
228
  signing_key:
411
229
  specification_version: 4
412
230
  summary: gRPC Ruby Framework