grpc 1.32.0-universal-darwin → 1.35.0-universal-darwin
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/etc/roots.pem +257 -573
- data/src/ruby/ext/grpc/extconf.rb +1 -1
- data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -16
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +70 -40
- data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.4/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.5/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.6/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.7/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +28 -0
- data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +18 -0
- data/src/ruby/pb/test/xds_client.rb +148 -23
- data/src/ruby/spec/pb/codegen/package_option_spec.rb +2 -6
- metadata +9 -9
@@ -39,11 +39,38 @@ require_relative '../src/proto/grpc/testing/empty_pb'
|
|
39
39
|
require_relative '../src/proto/grpc/testing/messages_pb'
|
40
40
|
require_relative '../src/proto/grpc/testing/test_services_pb'
|
41
41
|
|
42
|
+
class RpcConfig
|
43
|
+
def init(rpcs_to_send, metadata_to_send)
|
44
|
+
@rpcs_to_send = rpcs_to_send
|
45
|
+
@metadata_to_send = metadata_to_send
|
46
|
+
end
|
47
|
+
def rpcs_to_send
|
48
|
+
@rpcs_to_send
|
49
|
+
end
|
50
|
+
def metadata_to_send
|
51
|
+
@metadata_to_send
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Some global constant mappings
|
56
|
+
$RPC_MAP = {
|
57
|
+
'UnaryCall' => :UNARY_CALL,
|
58
|
+
'EmptyCall' => :EMPTY_CALL,
|
59
|
+
}
|
60
|
+
|
42
61
|
# Some global variables to be shared by server and client
|
43
62
|
$watchers = Array.new
|
44
63
|
$watchers_mutex = Mutex.new
|
45
64
|
$watchers_cv = ConditionVariable.new
|
46
65
|
$shutdown = false
|
66
|
+
# These can be configured by the test runner dynamically
|
67
|
+
$rpc_config = RpcConfig.new
|
68
|
+
$rpc_config.init([:UNARY_CALL], {})
|
69
|
+
# These stats are shared across threads
|
70
|
+
$accumulated_stats_mu = Mutex.new
|
71
|
+
$num_rpcs_started_by_method = {}
|
72
|
+
$num_rpcs_succeeded_by_method = {}
|
73
|
+
$num_rpcs_failed_by_method = {}
|
47
74
|
|
48
75
|
# RubyLogger defines a logger for gRPC based on the standard ruby logger.
|
49
76
|
module RubyLogger
|
@@ -71,6 +98,31 @@ def create_stub(opts)
|
|
71
98
|
)
|
72
99
|
end
|
73
100
|
|
101
|
+
class ConfigureTarget < Grpc::Testing::XdsUpdateClientConfigureService::Service
|
102
|
+
include Grpc::Testing
|
103
|
+
|
104
|
+
def configure(req, _call)
|
105
|
+
rpcs_to_send = req['types'];
|
106
|
+
metadata_to_send = {}
|
107
|
+
req['metadata'].each do |m|
|
108
|
+
rpc = m.type
|
109
|
+
if !metadata_to_send.key?(rpc)
|
110
|
+
metadata_to_send[rpc] = {}
|
111
|
+
end
|
112
|
+
metadata_key = m.key
|
113
|
+
metadata_value = m.value
|
114
|
+
metadata_to_send[rpc][metadata_key] = metadata_value
|
115
|
+
end
|
116
|
+
GRPC.logger.info("Configuring new rpcs_to_send and metadata_to_send...")
|
117
|
+
GRPC.logger.info(rpcs_to_send)
|
118
|
+
GRPC.logger.info(metadata_to_send)
|
119
|
+
new_rpc_config = RpcConfig.new
|
120
|
+
new_rpc_config.init(rpcs_to_send, metadata_to_send)
|
121
|
+
$rpc_config = new_rpc_config
|
122
|
+
ClientConfigureResponse.new();
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
74
126
|
# This implements LoadBalancerStatsService required by the test runner
|
75
127
|
class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
|
76
128
|
include Grpc::Testing
|
@@ -109,10 +161,20 @@ class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
|
|
109
161
|
num_failures: watcher['no_remote_peer'] + watcher['rpcs_needed']
|
110
162
|
);
|
111
163
|
end
|
164
|
+
|
165
|
+
def get_client_accumulated_stats(req, _call)
|
166
|
+
$accumulated_stats_mu.synchronize do
|
167
|
+
LoadBalancerAccumulatedStatsResponse.new(
|
168
|
+
num_rpcs_started_by_method: $num_rpcs_started_by_method,
|
169
|
+
num_rpcs_succeeded_by_method: $num_rpcs_succeeded_by_method,
|
170
|
+
num_rpcs_failed_by_method: $num_rpcs_failed_by_method
|
171
|
+
)
|
172
|
+
end
|
173
|
+
end
|
112
174
|
end
|
113
175
|
|
114
176
|
# execute 1 RPC and return remote hostname
|
115
|
-
def execute_rpc(op, fail_on_failed_rpcs)
|
177
|
+
def execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
|
116
178
|
remote_peer = ""
|
117
179
|
begin
|
118
180
|
op.execute
|
@@ -120,60 +182,108 @@ def execute_rpc(op, fail_on_failed_rpcs)
|
|
120
182
|
remote_peer = op.metadata['hostname']
|
121
183
|
end
|
122
184
|
rescue GRPC::BadStatus => e
|
123
|
-
GRPC.logger.info("ruby xds: rpc failed:|#{e.message}|, " \
|
124
|
-
"this may or may not be expected")
|
125
185
|
if fail_on_failed_rpcs
|
126
186
|
raise e
|
127
187
|
end
|
128
188
|
end
|
189
|
+
$accumulated_stats_mu.synchronize do
|
190
|
+
if remote_peer.empty?
|
191
|
+
$num_rpcs_failed_by_method[rpc_stats_key] += 1
|
192
|
+
else
|
193
|
+
$num_rpcs_succeeded_by_method[rpc_stats_key] += 1
|
194
|
+
end
|
195
|
+
end
|
129
196
|
remote_peer
|
130
197
|
end
|
131
198
|
|
199
|
+
def execute_rpc_in_thread(op, rpc_stats_key)
|
200
|
+
Thread.new {
|
201
|
+
begin
|
202
|
+
op.execute
|
203
|
+
# The following should _not_ happen with the current spec
|
204
|
+
# because we are only executing RPCs in a thread if we expect it
|
205
|
+
# to be kept open, or deadline_exceeded, or dropped by the load
|
206
|
+
# balancing policy. These RPCs should not complete successfully.
|
207
|
+
# Doing this for consistency
|
208
|
+
$accumulated_stats_mu.synchronize do
|
209
|
+
$num_rpcs_succeeded_by_method[rpc_stats_key] += 1
|
210
|
+
end
|
211
|
+
rescue GRPC::BadStatus => e
|
212
|
+
# Normal execution arrives here,
|
213
|
+
# either because of deadline_exceeded or "call dropped by load
|
214
|
+
# balancing policy"
|
215
|
+
$accumulated_stats_mu.synchronize do
|
216
|
+
$num_rpcs_failed_by_method[rpc_stats_key] += 1
|
217
|
+
end
|
218
|
+
end
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
132
222
|
# send 1 rpc every 1/qps second
|
133
|
-
def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs
|
134
|
-
rpcs_to_send, metadata_to_send)
|
223
|
+
def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs)
|
135
224
|
include Grpc::Testing
|
136
225
|
simple_req = SimpleRequest.new()
|
137
226
|
empty_req = Empty.new()
|
138
227
|
target_next_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
228
|
+
# Some RPCs are meant to be "kept open". Since Ruby does not have an
|
229
|
+
# async API, we are executing those RPCs in a thread so that they don't
|
230
|
+
# block.
|
231
|
+
keep_open_threads = Array.new
|
139
232
|
while !$shutdown
|
140
233
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
141
234
|
sleep_seconds = target_next_start - now
|
142
235
|
if sleep_seconds < 0
|
143
236
|
target_next_start = now + target_seconds_between_rpcs
|
144
|
-
GRPC.logger.info(
|
145
|
-
"ruby xds: warning, rpc takes too long to finish. " \
|
146
|
-
"Deficit = %.1fms. " \
|
147
|
-
"If you consistently see this, the qps is too high." \
|
148
|
-
% [(sleep_seconds * 1000).abs().round(1)])
|
149
237
|
else
|
150
238
|
target_next_start += target_seconds_between_rpcs
|
151
239
|
sleep(sleep_seconds)
|
152
240
|
end
|
153
241
|
deadline = GRPC::Core::TimeConsts::from_relative_time(30) # 30 seconds
|
154
242
|
results = {}
|
155
|
-
rpcs_to_send.each do |rpc|
|
156
|
-
|
157
|
-
|
243
|
+
$rpc_config.rpcs_to_send.each do |rpc|
|
244
|
+
# rpc is in the form of :UNARY_CALL or :EMPTY_CALL here
|
245
|
+
metadata = $rpc_config.metadata_to_send.key?(rpc) ?
|
246
|
+
$rpc_config.metadata_to_send[rpc] : {}
|
247
|
+
$accumulated_stats_mu.synchronize do
|
248
|
+
$num_rpcs_started_by_method[rpc.to_s] += 1
|
249
|
+
num_started = $num_rpcs_started_by_method[rpc.to_s]
|
250
|
+
if num_started % 100 == 0
|
251
|
+
GRPC.logger.info("Started #{num_started} of #{rpc}")
|
252
|
+
end
|
253
|
+
end
|
254
|
+
if rpc == :UNARY_CALL
|
158
255
|
op = stub.unary_call(simple_req,
|
159
256
|
metadata: metadata,
|
160
257
|
deadline: deadline,
|
161
258
|
return_op: true)
|
162
|
-
elsif rpc ==
|
259
|
+
elsif rpc == :EMPTY_CALL
|
163
260
|
op = stub.empty_call(empty_req,
|
164
261
|
metadata: metadata,
|
165
262
|
deadline: deadline,
|
166
263
|
return_op: true)
|
167
264
|
else
|
168
|
-
raise "Unsupported rpc
|
265
|
+
raise "Unsupported rpc #{rpc}"
|
266
|
+
end
|
267
|
+
rpc_stats_key = rpc.to_s
|
268
|
+
if metadata.key?('rpc-behavior') and
|
269
|
+
(metadata['rpc-behavior'] == 'keep-open')
|
270
|
+
num_open_threads = keep_open_threads.size
|
271
|
+
if num_open_threads % 50 == 0
|
272
|
+
GRPC.logger.info("number of keep_open_threads = #{num_open_threads}")
|
273
|
+
end
|
274
|
+
keep_open_threads << execute_rpc_in_thread(op, rpc_stats_key)
|
275
|
+
else
|
276
|
+
results[rpc] = execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
|
169
277
|
end
|
170
|
-
results[rpc] = execute_rpc(op, fail_on_failed_rpcs)
|
171
278
|
end
|
172
279
|
$watchers_mutex.synchronize do
|
173
280
|
$watchers.each do |watcher|
|
174
281
|
# this is counted once when each group of all rpcs_to_send were done
|
175
282
|
watcher['rpcs_needed'] -= 1
|
176
283
|
results.each do |rpc_name, remote_peer|
|
284
|
+
# These stats expect rpc_name to be in the form of
|
285
|
+
# UnaryCall or EmptyCall, not the underscore-case all-caps form
|
286
|
+
rpc_name = $RPC_MAP.invert()[rpc_name]
|
177
287
|
if remote_peer.strip.empty?
|
178
288
|
# error is counted per individual RPC
|
179
289
|
watcher['no_remote_peer'] += 1
|
@@ -191,6 +301,7 @@ def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
|
|
191
301
|
$watchers_cv.broadcast
|
192
302
|
end
|
193
303
|
end
|
304
|
+
keep_open_threads.each { |thd| thd.join }
|
194
305
|
end
|
195
306
|
|
196
307
|
# Args is used to hold the command line info.
|
@@ -242,18 +353,22 @@ def main
|
|
242
353
|
s = GRPC::RpcServer.new
|
243
354
|
s.add_http2_port(host, :this_port_is_insecure)
|
244
355
|
s.handle(TestTarget)
|
356
|
+
s.handle(ConfigureTarget)
|
245
357
|
server_thread = Thread.new {
|
246
358
|
# run the server until the main test runner terminates this process
|
247
359
|
s.run_till_terminated_or_interrupted(['TERM'])
|
248
360
|
}
|
249
361
|
|
250
|
-
#
|
362
|
+
# Initialize stats
|
363
|
+
$RPC_MAP.values.each do |rpc|
|
364
|
+
$num_rpcs_started_by_method[rpc.to_s] = 0
|
365
|
+
$num_rpcs_succeeded_by_method[rpc.to_s] = 0
|
366
|
+
$num_rpcs_failed_by_method[rpc.to_s] = 0
|
367
|
+
end
|
368
|
+
|
369
|
+
# The client just sends rpcs continuously in a regular interval
|
251
370
|
stub = create_stub(opts)
|
252
371
|
target_seconds_between_rpcs = (1.0 / opts['qps'].to_f)
|
253
|
-
rpcs_to_send = []
|
254
|
-
if opts['rpc']
|
255
|
-
rpcs_to_send = opts['rpc'].split(',')
|
256
|
-
end
|
257
372
|
# Convert 'metadata' input in the form of
|
258
373
|
# rpc1:k1:v1,rpc2:k2:v2,rpc1:k3:v3
|
259
374
|
# into
|
@@ -266,11 +381,13 @@ def main
|
|
266
381
|
# 'k2' => 'v2'
|
267
382
|
# },
|
268
383
|
# }
|
384
|
+
rpcs_to_send = []
|
269
385
|
metadata_to_send = {}
|
270
386
|
if opts['metadata']
|
271
387
|
metadata_entries = opts['metadata'].split(',')
|
272
388
|
metadata_entries.each do |e|
|
273
389
|
(rpc_name, metadata_key, metadata_value) = e.split(':')
|
390
|
+
rpc_name = $RPC_MAP[rpc_name]
|
274
391
|
# initialize if we haven't seen this rpc_name yet
|
275
392
|
if !metadata_to_send.key?(rpc_name)
|
276
393
|
metadata_to_send[rpc_name] = {}
|
@@ -278,12 +395,20 @@ def main
|
|
278
395
|
metadata_to_send[rpc_name][metadata_key] = metadata_value
|
279
396
|
end
|
280
397
|
end
|
398
|
+
if opts['rpc']
|
399
|
+
rpcs_to_send = opts['rpc'].split(',')
|
400
|
+
end
|
401
|
+
if rpcs_to_send.size > 0
|
402
|
+
rpcs_to_send.map! { |rpc| $RPC_MAP[rpc] }
|
403
|
+
new_rpc_config = RpcConfig.new
|
404
|
+
new_rpc_config.init(rpcs_to_send, metadata_to_send)
|
405
|
+
$rpc_config = new_rpc_config
|
406
|
+
end
|
281
407
|
client_threads = Array.new
|
282
408
|
opts['num_channels'].times {
|
283
409
|
client_threads << Thread.new {
|
284
410
|
run_test_loop(stub, target_seconds_between_rpcs,
|
285
|
-
opts['fail_on_failed_rpcs']
|
286
|
-
rpcs_to_send, metadata_to_send)
|
411
|
+
opts['fail_on_failed_rpcs'])
|
287
412
|
}
|
288
413
|
}
|
289
414
|
|
@@ -71,14 +71,10 @@ describe 'Code Generation Options' do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def with_protos(file_paths)
|
74
|
-
fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG']
|
75
|
-
bins_sub_dir = ENV['CONFIG']
|
76
|
-
|
77
74
|
pb_dir = File.dirname(__FILE__)
|
78
|
-
bins_dir = File.join('..', '..', '..', '..', '..', '
|
79
|
-
|
75
|
+
bins_dir = File.join('..', '..', '..', '..', '..', 'cmake', 'build')
|
80
76
|
plugin = File.join(bins_dir, 'grpc_ruby_plugin')
|
81
|
-
protoc = File.join(bins_dir, 'protobuf', 'protoc')
|
77
|
+
protoc = File.join(bins_dir, 'third_party', 'protobuf', 'protoc')
|
82
78
|
|
83
79
|
# Generate the service from the proto
|
84
80
|
Dir.mktmpdir(nil, File.dirname(__FILE__)) do |tmp_dir|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.35.0
|
5
5
|
platform: universal-darwin
|
6
6
|
authors:
|
7
7
|
- gRPC Authors
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: src/ruby/bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3.
|
19
|
+
version: '3.14'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '3.
|
26
|
+
version: '3.14'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: googleapis-common-protos-types
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -330,7 +330,7 @@ homepage: https://github.com/google/grpc/tree/master/src/ruby
|
|
330
330
|
licenses:
|
331
331
|
- Apache-2.0
|
332
332
|
metadata: {}
|
333
|
-
post_install_message:
|
333
|
+
post_install_message:
|
334
334
|
rdoc_options: []
|
335
335
|
require_paths:
|
336
336
|
- src/ruby/lib
|
@@ -343,15 +343,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
343
343
|
version: '2.3'
|
344
344
|
- - "<"
|
345
345
|
- !ruby/object:Gem::Version
|
346
|
-
version:
|
346
|
+
version: 3.1.dev
|
347
347
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
348
348
|
requirements:
|
349
349
|
- - ">="
|
350
350
|
- !ruby/object:Gem::Version
|
351
351
|
version: '0'
|
352
352
|
requirements: []
|
353
|
-
rubygems_version: 3.
|
354
|
-
signing_key:
|
353
|
+
rubygems_version: 3.2.6
|
354
|
+
signing_key:
|
355
355
|
specification_version: 4
|
356
356
|
summary: GRPC system in Ruby
|
357
357
|
test_files:
|