grpc 1.33.0.pre1-x86-linux → 1.37.0.pre1-x86-linux
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 +10 -2
- data/src/ruby/ext/grpc/rb_channel.c +10 -1
- data/src/ruby/ext/grpc/rb_channel_credentials.c +11 -1
- data/src/ruby/ext/grpc/rb_channel_credentials.h +4 -0
- data/src/ruby/ext/grpc/rb_compression_options.c +1 -1
- data/src/ruby/ext/grpc/rb_enable_cpp.cc +1 -1
- data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc.c +4 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -14
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +70 -37
- data/src/ruby/ext/grpc/rb_server.c +13 -1
- data/src/ruby/ext/grpc/rb_server_credentials.c +19 -3
- data/src/ruby/ext/grpc/rb_server_credentials.h +4 -0
- data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +215 -0
- data/src/ruby/ext/grpc/rb_xds_channel_credentials.h +35 -0
- data/src/ruby/ext/grpc/rb_xds_server_credentials.c +169 -0
- data/src/ruby/ext/grpc/rb_xds_server_credentials.h +35 -0
- data/src/ruby/lib/grpc/2.4/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/generic/client_stub.rb +4 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +35 -0
- data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +18 -0
- data/src/ruby/pb/test/xds_client.rb +166 -25
- data/src/ruby/spec/call_spec.rb +1 -1
- data/src/ruby/spec/channel_credentials_spec.rb +32 -0
- data/src/ruby/spec/channel_spec.rb +17 -6
- data/src/ruby/spec/client_auth_spec.rb +27 -1
- data/src/ruby/spec/errors_spec.rb +1 -1
- data/src/ruby/spec/generic/active_call_spec.rb +2 -2
- data/src/ruby/spec/generic/client_stub_spec.rb +4 -4
- data/src/ruby/spec/generic/rpc_server_spec.rb +1 -1
- data/src/ruby/spec/pb/codegen/package_option_spec.rb +2 -6
- data/src/ruby/spec/server_credentials_spec.rb +25 -0
- data/src/ruby/spec/server_spec.rb +22 -0
- metadata +40 -36
- data/src/ruby/lib/grpc/2.3/grpc_c.so +0 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2021 gRPC authors.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*
|
17
|
+
*/
|
18
|
+
|
19
|
+
#ifndef GRPC_RB_XDS_SERVER_CREDENTIALS_H_
|
20
|
+
#define GRPC_RB_XDS_SERVER_CREDENTIALS_H_
|
21
|
+
|
22
|
+
#include <grpc/grpc_security.h>
|
23
|
+
#include <ruby/ruby.h>
|
24
|
+
#include <stdbool.h>
|
25
|
+
|
26
|
+
/* Initializes the ruby XdsServerCredentials class. */
|
27
|
+
void Init_grpc_xds_server_credentials();
|
28
|
+
|
29
|
+
/* Gets the wrapped server_credentials from the ruby wrapper */
|
30
|
+
grpc_server_credentials* grpc_rb_get_wrapped_xds_server_credentials(VALUE v);
|
31
|
+
|
32
|
+
/* Check if v is kind of XdsServerCredentials */
|
33
|
+
bool grpc_rb_is_xds_server_credentials(VALUE v);
|
34
|
+
|
35
|
+
#endif /* GRPC_RB_XDS_SERVER_CREDENTIALS_H_ */
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -41,8 +41,10 @@ module GRPC
|
|
41
41
|
channel_args['grpc.primary_user_agent'] += ' '
|
42
42
|
end
|
43
43
|
channel_args['grpc.primary_user_agent'] += "grpc-ruby/#{VERSION}"
|
44
|
-
unless creds.is_a?(Core::ChannelCredentials) ||
|
45
|
-
|
44
|
+
unless creds.is_a?(Core::ChannelCredentials) ||
|
45
|
+
creds.is_a?(Core::XdsChannelCredentials) ||
|
46
|
+
creds.is_a?(Symbol)
|
47
|
+
fail(TypeError, 'creds is not a ChannelCredentials, XdsChannelCredentials, or Symbol')
|
46
48
|
end
|
47
49
|
Core::Channel.new(host, channel_args, creds)
|
48
50
|
end
|
@@ -76,6 +76,34 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
76
76
|
add_message "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer" do
|
77
77
|
map :rpcs_by_peer, :string, :int32, 1
|
78
78
|
end
|
79
|
+
add_message "grpc.testing.LoadBalancerAccumulatedStatsRequest" do
|
80
|
+
end
|
81
|
+
add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse" do
|
82
|
+
map :num_rpcs_started_by_method, :string, :int32, 1
|
83
|
+
map :num_rpcs_succeeded_by_method, :string, :int32, 2
|
84
|
+
map :num_rpcs_failed_by_method, :string, :int32, 3
|
85
|
+
map :stats_per_method, :string, :message, 4, "grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats"
|
86
|
+
end
|
87
|
+
add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats" do
|
88
|
+
optional :rpcs_started, :int32, 1
|
89
|
+
map :result, :int32, :int32, 2
|
90
|
+
end
|
91
|
+
add_message "grpc.testing.ClientConfigureRequest" do
|
92
|
+
repeated :types, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
|
93
|
+
repeated :metadata, :message, 2, "grpc.testing.ClientConfigureRequest.Metadata"
|
94
|
+
optional :timeout_sec, :int32, 3
|
95
|
+
end
|
96
|
+
add_message "grpc.testing.ClientConfigureRequest.Metadata" do
|
97
|
+
optional :type, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
|
98
|
+
optional :key, :string, 2
|
99
|
+
optional :value, :string, 3
|
100
|
+
end
|
101
|
+
add_enum "grpc.testing.ClientConfigureRequest.RpcType" do
|
102
|
+
value :EMPTY_CALL, 0
|
103
|
+
value :UNARY_CALL, 1
|
104
|
+
end
|
105
|
+
add_message "grpc.testing.ClientConfigureResponse" do
|
106
|
+
end
|
79
107
|
add_enum "grpc.testing.PayloadType" do
|
80
108
|
value :COMPRESSABLE, 0
|
81
109
|
end
|
@@ -104,6 +132,13 @@ module Grpc
|
|
104
132
|
LoadBalancerStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsRequest").msgclass
|
105
133
|
LoadBalancerStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse").msgclass
|
106
134
|
LoadBalancerStatsResponse::RpcsByPeer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse.RpcsByPeer").msgclass
|
135
|
+
LoadBalancerAccumulatedStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsRequest").msgclass
|
136
|
+
LoadBalancerAccumulatedStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse").msgclass
|
137
|
+
LoadBalancerAccumulatedStatsResponse::MethodStats = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse.MethodStats").msgclass
|
138
|
+
ClientConfigureRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest").msgclass
|
139
|
+
ClientConfigureRequest::Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.Metadata").msgclass
|
140
|
+
ClientConfigureRequest::RpcType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.RpcType").enummodule
|
141
|
+
ClientConfigureResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureResponse").msgclass
|
107
142
|
PayloadType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
|
108
143
|
GrpclbRouteType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.GrpclbRouteType").enummodule
|
109
144
|
end
|
@@ -110,6 +110,8 @@ module Grpc
|
|
110
110
|
|
111
111
|
# Gets the backend distribution for RPCs sent by a test client.
|
112
112
|
rpc :GetClientStats, ::Grpc::Testing::LoadBalancerStatsRequest, ::Grpc::Testing::LoadBalancerStatsResponse
|
113
|
+
# Gets the accumulated stats for RPCs sent by a test client.
|
114
|
+
rpc :GetClientAccumulatedStats, ::Grpc::Testing::LoadBalancerAccumulatedStatsRequest, ::Grpc::Testing::LoadBalancerAccumulatedStatsResponse
|
113
115
|
end
|
114
116
|
|
115
117
|
Stub = Service.rpc_stub_class
|
@@ -128,6 +130,22 @@ module Grpc
|
|
128
130
|
rpc :SetNotServing, ::Grpc::Testing::Empty, ::Grpc::Testing::Empty
|
129
131
|
end
|
130
132
|
|
133
|
+
Stub = Service.rpc_stub_class
|
134
|
+
end
|
135
|
+
module XdsUpdateClientConfigureService
|
136
|
+
# A service to dynamically update the configuration of an xDS test client.
|
137
|
+
class Service
|
138
|
+
|
139
|
+
include GRPC::GenericService
|
140
|
+
|
141
|
+
self.marshal_class_method = :encode
|
142
|
+
self.unmarshal_class_method = :decode
|
143
|
+
self.service_name = 'grpc.testing.XdsUpdateClientConfigureService'
|
144
|
+
|
145
|
+
# Update the tes client's configuration.
|
146
|
+
rpc :Configure, ::Grpc::Testing::ClientConfigureRequest, ::Grpc::Testing::ClientConfigureResponse
|
147
|
+
end
|
148
|
+
|
131
149
|
Stub = Service.rpc_stub_class
|
132
150
|
end
|
133
151
|
end
|
@@ -39,11 +39,35 @@ 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
|
+
attr_reader :rpcs_to_send, :metadata_to_send, :timeout_sec
|
44
|
+
def init(rpcs_to_send, metadata_to_send, timeout_sec = 0)
|
45
|
+
@rpcs_to_send = rpcs_to_send
|
46
|
+
@metadata_to_send = metadata_to_send
|
47
|
+
@timeout_sec = timeout_sec
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Some global constant mappings
|
52
|
+
$RPC_MAP = {
|
53
|
+
'UnaryCall' => :UNARY_CALL,
|
54
|
+
'EmptyCall' => :EMPTY_CALL,
|
55
|
+
}
|
56
|
+
|
42
57
|
# Some global variables to be shared by server and client
|
43
58
|
$watchers = Array.new
|
44
59
|
$watchers_mutex = Mutex.new
|
45
60
|
$watchers_cv = ConditionVariable.new
|
46
61
|
$shutdown = false
|
62
|
+
# These can be configured by the test runner dynamically
|
63
|
+
$rpc_config = RpcConfig.new
|
64
|
+
$rpc_config.init([:UNARY_CALL], {})
|
65
|
+
# These stats are shared across threads
|
66
|
+
$accumulated_stats_mu = Mutex.new
|
67
|
+
$num_rpcs_started_by_method = {}
|
68
|
+
$num_rpcs_succeeded_by_method = {}
|
69
|
+
$num_rpcs_failed_by_method = {}
|
70
|
+
$accumulated_method_stats = {}
|
47
71
|
|
48
72
|
# RubyLogger defines a logger for gRPC based on the standard ruby logger.
|
49
73
|
module RubyLogger
|
@@ -71,6 +95,41 @@ def create_stub(opts)
|
|
71
95
|
)
|
72
96
|
end
|
73
97
|
|
98
|
+
class StatsPerMethod
|
99
|
+
attr_reader :rpcs_started, :result
|
100
|
+
def initialize()
|
101
|
+
@rpcs_started = 0
|
102
|
+
@result = Hash.new(0)
|
103
|
+
end
|
104
|
+
def increment_rpcs_started()
|
105
|
+
@rpcs_started += 1
|
106
|
+
end
|
107
|
+
def add_result(status_code)
|
108
|
+
@result[status_code] += 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class ConfigureTarget < Grpc::Testing::XdsUpdateClientConfigureService::Service
|
113
|
+
include Grpc::Testing
|
114
|
+
|
115
|
+
def configure(req, _call)
|
116
|
+
metadata_to_send = {}
|
117
|
+
req.metadata.each do |m|
|
118
|
+
rpc = m.type
|
119
|
+
if !metadata_to_send.key?(rpc)
|
120
|
+
metadata_to_send[rpc] = {}
|
121
|
+
end
|
122
|
+
metadata_key = m.key
|
123
|
+
metadata_value = m.value
|
124
|
+
metadata_to_send[rpc][metadata_key] = metadata_value
|
125
|
+
end
|
126
|
+
new_rpc_config = RpcConfig.new
|
127
|
+
new_rpc_config.init(req['types'], metadata_to_send, req['timeout_sec'])
|
128
|
+
$rpc_config = new_rpc_config
|
129
|
+
ClientConfigureResponse.new()
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
74
133
|
# This implements LoadBalancerStatsService required by the test runner
|
75
134
|
class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
|
76
135
|
include Grpc::Testing
|
@@ -107,73 +166,139 @@ class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
|
|
107
166
|
rpcs_by_method: rpcs_by_method,
|
108
167
|
rpcs_by_peer: watcher['rpcs_by_peer'],
|
109
168
|
num_failures: watcher['no_remote_peer'] + watcher['rpcs_needed']
|
110
|
-
)
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_client_accumulated_stats(req, _call)
|
173
|
+
$accumulated_stats_mu.synchronize do
|
174
|
+
all_stats_per_method = $accumulated_method_stats.map { |rpc, stats_per_method|
|
175
|
+
[rpc,
|
176
|
+
LoadBalancerAccumulatedStatsResponse::MethodStats.new(
|
177
|
+
rpcs_started: stats_per_method.rpcs_started,
|
178
|
+
result: stats_per_method.result
|
179
|
+
)]
|
180
|
+
}.to_h
|
181
|
+
LoadBalancerAccumulatedStatsResponse.new(
|
182
|
+
num_rpcs_started_by_method: $num_rpcs_started_by_method,
|
183
|
+
num_rpcs_succeeded_by_method: $num_rpcs_succeeded_by_method,
|
184
|
+
num_rpcs_failed_by_method: $num_rpcs_failed_by_method,
|
185
|
+
stats_per_method: all_stats_per_method,
|
186
|
+
)
|
187
|
+
end
|
111
188
|
end
|
112
189
|
end
|
113
190
|
|
114
191
|
# execute 1 RPC and return remote hostname
|
115
|
-
def execute_rpc(op, fail_on_failed_rpcs)
|
192
|
+
def execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
|
116
193
|
remote_peer = ""
|
194
|
+
status_code = 0
|
117
195
|
begin
|
118
196
|
op.execute
|
119
197
|
if op.metadata.key?('hostname')
|
120
198
|
remote_peer = op.metadata['hostname']
|
121
199
|
end
|
122
200
|
rescue GRPC::BadStatus => e
|
123
|
-
GRPC.logger.info("ruby xds: rpc failed:|#{e.message}|, " \
|
124
|
-
"this may or may not be expected")
|
125
201
|
if fail_on_failed_rpcs
|
126
202
|
raise e
|
127
203
|
end
|
204
|
+
status_code = e.code
|
205
|
+
end
|
206
|
+
$accumulated_stats_mu.synchronize do
|
207
|
+
$accumulated_method_stats[rpc_stats_key].add_result(status_code)
|
208
|
+
if remote_peer.empty?
|
209
|
+
$num_rpcs_failed_by_method[rpc_stats_key] += 1
|
210
|
+
else
|
211
|
+
$num_rpcs_succeeded_by_method[rpc_stats_key] += 1
|
212
|
+
end
|
128
213
|
end
|
129
214
|
remote_peer
|
130
215
|
end
|
131
216
|
|
217
|
+
def execute_rpc_in_thread(op, rpc_stats_key)
|
218
|
+
Thread.new {
|
219
|
+
begin
|
220
|
+
op.execute
|
221
|
+
# The following should _not_ happen with the current spec
|
222
|
+
# because we are only executing RPCs in a thread if we expect it
|
223
|
+
# to be kept open, or deadline_exceeded, or dropped by the load
|
224
|
+
# balancing policy. These RPCs should not complete successfully.
|
225
|
+
# Doing this for consistency
|
226
|
+
$accumulated_stats_mu.synchronize do
|
227
|
+
$num_rpcs_succeeded_by_method[rpc_stats_key] += 1
|
228
|
+
$accumulated_method_stats[rpc_stats_key].add_result(0)
|
229
|
+
end
|
230
|
+
rescue GRPC::BadStatus => e
|
231
|
+
# Normal execution arrives here,
|
232
|
+
# either because of deadline_exceeded or "call dropped by load
|
233
|
+
# balancing policy"
|
234
|
+
$accumulated_stats_mu.synchronize do
|
235
|
+
$num_rpcs_failed_by_method[rpc_stats_key] += 1
|
236
|
+
$accumulated_method_stats[rpc_stats_key].add_result(e.code)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
}
|
240
|
+
end
|
241
|
+
|
132
242
|
# 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)
|
243
|
+
def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs)
|
135
244
|
include Grpc::Testing
|
136
245
|
simple_req = SimpleRequest.new()
|
137
246
|
empty_req = Empty.new()
|
138
247
|
target_next_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
248
|
+
# Some RPCs are meant to be "kept open". Since Ruby does not have an
|
249
|
+
# async API, we are executing those RPCs in a thread so that they don't
|
250
|
+
# block.
|
251
|
+
keep_open_threads = Array.new
|
139
252
|
while !$shutdown
|
140
253
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
141
254
|
sleep_seconds = target_next_start - now
|
142
255
|
if sleep_seconds < 0
|
143
256
|
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
257
|
else
|
150
258
|
target_next_start += target_seconds_between_rpcs
|
151
259
|
sleep(sleep_seconds)
|
152
260
|
end
|
153
|
-
|
261
|
+
deadline_sec = $rpc_config.timeout_sec > 0 ? $rpc_config.timeout_sec : 30
|
262
|
+
deadline = GRPC::Core::TimeConsts::from_relative_time(deadline_sec)
|
154
263
|
results = {}
|
155
|
-
rpcs_to_send.each do |rpc|
|
156
|
-
|
157
|
-
|
264
|
+
$rpc_config.rpcs_to_send.each do |rpc|
|
265
|
+
# rpc is in the form of :UNARY_CALL or :EMPTY_CALL here
|
266
|
+
metadata = $rpc_config.metadata_to_send.key?(rpc) ?
|
267
|
+
$rpc_config.metadata_to_send[rpc] : {}
|
268
|
+
$accumulated_stats_mu.synchronize do
|
269
|
+
$num_rpcs_started_by_method[rpc.to_s] += 1
|
270
|
+
$accumulated_method_stats[rpc.to_s].increment_rpcs_started()
|
271
|
+
end
|
272
|
+
if rpc == :UNARY_CALL
|
158
273
|
op = stub.unary_call(simple_req,
|
159
274
|
metadata: metadata,
|
160
275
|
deadline: deadline,
|
161
276
|
return_op: true)
|
162
|
-
elsif rpc ==
|
277
|
+
elsif rpc == :EMPTY_CALL
|
163
278
|
op = stub.empty_call(empty_req,
|
164
279
|
metadata: metadata,
|
165
280
|
deadline: deadline,
|
166
281
|
return_op: true)
|
167
282
|
else
|
168
|
-
raise "Unsupported rpc
|
283
|
+
raise "Unsupported rpc #{rpc}"
|
284
|
+
end
|
285
|
+
rpc_stats_key = rpc.to_s
|
286
|
+
if metadata.key?('rpc-behavior') and
|
287
|
+
((metadata['rpc-behavior'] == 'keep-open') or
|
288
|
+
(metadata['rpc-behavior'].start_with?('sleep')))
|
289
|
+
keep_open_threads << execute_rpc_in_thread(op, rpc_stats_key)
|
290
|
+
else
|
291
|
+
results[rpc] = execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
|
169
292
|
end
|
170
|
-
results[rpc] = execute_rpc(op, fail_on_failed_rpcs)
|
171
293
|
end
|
172
294
|
$watchers_mutex.synchronize do
|
173
295
|
$watchers.each do |watcher|
|
174
296
|
# this is counted once when each group of all rpcs_to_send were done
|
175
297
|
watcher['rpcs_needed'] -= 1
|
176
298
|
results.each do |rpc_name, remote_peer|
|
299
|
+
# These stats expect rpc_name to be in the form of
|
300
|
+
# UnaryCall or EmptyCall, not the underscore-case all-caps form
|
301
|
+
rpc_name = $RPC_MAP.invert()[rpc_name]
|
177
302
|
if remote_peer.strip.empty?
|
178
303
|
# error is counted per individual RPC
|
179
304
|
watcher['no_remote_peer'] += 1
|
@@ -191,6 +316,7 @@ def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
|
|
191
316
|
$watchers_cv.broadcast
|
192
317
|
end
|
193
318
|
end
|
319
|
+
keep_open_threads.each { |thd| thd.join }
|
194
320
|
end
|
195
321
|
|
196
322
|
# Args is used to hold the command line info.
|
@@ -242,18 +368,23 @@ def main
|
|
242
368
|
s = GRPC::RpcServer.new
|
243
369
|
s.add_http2_port(host, :this_port_is_insecure)
|
244
370
|
s.handle(TestTarget)
|
371
|
+
s.handle(ConfigureTarget)
|
245
372
|
server_thread = Thread.new {
|
246
373
|
# run the server until the main test runner terminates this process
|
247
374
|
s.run_till_terminated_or_interrupted(['TERM'])
|
248
375
|
}
|
249
376
|
|
250
|
-
#
|
377
|
+
# Initialize stats
|
378
|
+
$RPC_MAP.values.each do |rpc|
|
379
|
+
$num_rpcs_started_by_method[rpc.to_s] = 0
|
380
|
+
$num_rpcs_succeeded_by_method[rpc.to_s] = 0
|
381
|
+
$num_rpcs_failed_by_method[rpc.to_s] = 0
|
382
|
+
$accumulated_method_stats[rpc.to_s] = StatsPerMethod.new
|
383
|
+
end
|
384
|
+
|
385
|
+
# The client just sends rpcs continuously in a regular interval
|
251
386
|
stub = create_stub(opts)
|
252
387
|
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
388
|
# Convert 'metadata' input in the form of
|
258
389
|
# rpc1:k1:v1,rpc2:k2:v2,rpc1:k3:v3
|
259
390
|
# into
|
@@ -266,11 +397,13 @@ def main
|
|
266
397
|
# 'k2' => 'v2'
|
267
398
|
# },
|
268
399
|
# }
|
400
|
+
rpcs_to_send = []
|
269
401
|
metadata_to_send = {}
|
270
402
|
if opts['metadata']
|
271
403
|
metadata_entries = opts['metadata'].split(',')
|
272
404
|
metadata_entries.each do |e|
|
273
405
|
(rpc_name, metadata_key, metadata_value) = e.split(':')
|
406
|
+
rpc_name = $RPC_MAP[rpc_name]
|
274
407
|
# initialize if we haven't seen this rpc_name yet
|
275
408
|
if !metadata_to_send.key?(rpc_name)
|
276
409
|
metadata_to_send[rpc_name] = {}
|
@@ -278,12 +411,20 @@ def main
|
|
278
411
|
metadata_to_send[rpc_name][metadata_key] = metadata_value
|
279
412
|
end
|
280
413
|
end
|
414
|
+
if opts['rpc']
|
415
|
+
rpcs_to_send = opts['rpc'].split(',')
|
416
|
+
end
|
417
|
+
if rpcs_to_send.size > 0
|
418
|
+
rpcs_to_send.map! { |rpc| $RPC_MAP[rpc] }
|
419
|
+
new_rpc_config = RpcConfig.new
|
420
|
+
new_rpc_config.init(rpcs_to_send, metadata_to_send)
|
421
|
+
$rpc_config = new_rpc_config
|
422
|
+
end
|
281
423
|
client_threads = Array.new
|
282
424
|
opts['num_channels'].times {
|
283
425
|
client_threads << Thread.new {
|
284
426
|
run_test_loop(stub, target_seconds_between_rpcs,
|
285
|
-
opts['fail_on_failed_rpcs']
|
286
|
-
rpcs_to_send, metadata_to_send)
|
427
|
+
opts['fail_on_failed_rpcs'])
|
287
428
|
}
|
288
429
|
}
|
289
430
|
|