gruf 2.16.2 → 2.18.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/gruf.gemspec +1 -15
- data/lib/gruf/client.rb +5 -1
- data/lib/gruf/configuration.rb +2 -0
- data/lib/gruf/controllers/autoloader.rb +17 -10
- data/lib/gruf/controllers/base.rb +0 -1
- data/lib/gruf/controllers/service_binder.rb +41 -36
- data/lib/gruf/interceptors/active_record/connection_reset.rb +11 -2
- data/lib/gruf/version.rb +1 -1
- metadata +4 -186
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3de94291c905860137fbeb2be431f470af5929eddd3df869b602944dbe3253ea
|
4
|
+
data.tar.gz: 282cd45242df875e8c664a9434bb7364592a5062e4d3d4980972d9a314931996
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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 =
|
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
|
|
data/lib/gruf/configuration.rb
CHANGED
@@ -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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
81
|
-
@
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
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
|
-
|
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
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.
|
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:
|
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.
|
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.
|
227
|
+
rubygems_version: 3.4.10
|
410
228
|
signing_key:
|
411
229
|
specification_version: 4
|
412
230
|
summary: gRPC Ruby Framework
|